diff --git a/README.md b/README.md index c2e3756ac234bfc4be5aba2a7bc31912ef75e313..620a51b9229699821cb0961af2a1dc6a5436c3c7 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ inital readme + +cookieKey1 = random +cookieKey2 = random diff --git a/package-lock.json b/package-lock.json index dc481fc23b5f58b173fdc5da528b533e8bc98a3b..3e1c267cb4c0781134a9f1bd1c2bed559412e995 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1049,6 +1049,14 @@ "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, "babel-jest": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz", @@ -1180,6 +1188,11 @@ } } }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -1722,6 +1735,16 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, + "cookie-session": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-1.4.0.tgz", + "integrity": "sha512-0hhwD+BUIwMXQraiZP/J7VP2YFzqo6g4WqZlWHtEHQ22t0MeZZrNBSCxC1zcaLAs8ApT3BzAKizx9gW/AP9vNA==", + "requires": { + "cookies": "0.8.0", + "debug": "2.6.9", + "on-headers": "~1.0.2" + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -1733,6 +1756,22 @@ "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", "dev": true }, + "cookies": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", + "requires": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -2832,6 +2871,24 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4209,6 +4266,14 @@ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==" }, + "keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "requires": { + "tsscmp": "1.0.6" + } + }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -4719,6 +4784,11 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4930,6 +5000,32 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-oauth2": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", + "requires": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4959,6 +5055,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -6394,6 +6495,11 @@ "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true }, + "tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" + }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", @@ -6457,6 +6563,11 @@ "is-typedarray": "^1.0.0" } }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, "undefsafe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", diff --git a/package.json b/package.json index 0e3e37281350807feb1db900d40feecb74d3a9b9..dc69eedd5e846f38d255be157829d8c0e805dbcf 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "author": "DevTeam", "license": "MIT", "dependencies": { + "axios": "^0.19.2", "body-parser": "^1.19.0", + "cookie-session": "^1.4.0", "cors": "^2.8.5", "cuid": "^2.1.8", "dotenv": "^8.2.0", @@ -24,6 +26,8 @@ "lodash": "^4.17.18", "mongoose": "^5.9.22", "morgan": "^1.10.0", + "passport": "^0.4.1", + "passport-oauth2": "^1.5.0", "validator": "^13.1.1" }, "devDependencies": { diff --git a/src/auth.js b/src/auth.js new file mode 100644 index 0000000000000000000000000000000000000000..0dc9c2016a41af030464e065d938d7b4b8d4ba3f --- /dev/null +++ b/src/auth.js @@ -0,0 +1,13 @@ +// Is authenticated +const isLoggedIn = (req, res, next) => { + if (req.user) { + next() + } else { + res.status(401).end() + } +} + +// Permissions +// TODO + +exports.isLoggedIn = isLoggedIn diff --git a/src/resources/activity/activity.controllers.js b/src/resources/activity/activity.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..b6e0c4ebfe7cea7d57b2099ed2853d8d0489807e --- /dev/null +++ b/src/resources/activity/activity.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Activity } = require('./activity.model') + +exports.default = crudControllers(Activity) diff --git a/src/resources/activity/activity.model.js b/src/resources/activity/activity.model.js new file mode 100644 index 0000000000000000000000000000000000000000..2cd33663b5ebc7c275649264ce6f8f1cc0c798b6 --- /dev/null +++ b/src/resources/activity/activity.model.js @@ -0,0 +1,37 @@ +const mongoose = require('mongoose') + +const ActivitySchema = new mongoose.Schema( + { + title: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + date: { + type: Date, + required: true, + }, + type: { + type: ['class', 'optional', 'camp'], + required: true, + }, + comment: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'comment', + required: true, + }, + ], + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Activity = mongoose.model('activity', ActivitySchema) + +exports.Activity = Activity diff --git a/src/resources/activity/activity.router.js b/src/resources/activity/activity.router.js new file mode 100644 index 0000000000000000000000000000000000000000..4f5f72d3756b662dd468035d59a00941ff211fc4 --- /dev/null +++ b/src/resources/activity/activity.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./activity.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/application/application.controllers.js b/src/resources/application/application.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..a434abde670df6c55245bd2e76a91f2b8245421e --- /dev/null +++ b/src/resources/application/application.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Application } = require('./application.model') + +exports.default = crudControllers(Application) diff --git a/src/resources/application/application.model.js b/src/resources/application/application.model.js new file mode 100644 index 0000000000000000000000000000000000000000..50683f2058ad245e052c2ae1c9ca75a3ea60b7e0 --- /dev/null +++ b/src/resources/application/application.model.js @@ -0,0 +1,28 @@ +const mongoose = require('mongoose') + +const ApplicationSchema = new mongoose.Schema({ + motivation: { + type: String, + required: true, + }, + expectation: { + type: String, + required: true, + }, + solution: { + type: String, + required: true, + }, + groups: { + type: mongoose.Schema.Types.ObjectId, + ref: 'groups', + required: true, + }, +}) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Application = mongoose.model('application', ApplicationSchema) + +exports.Application = Application diff --git a/src/resources/application/application.router.js b/src/resources/application/application.router.js new file mode 100644 index 0000000000000000000000000000000000000000..814cb581e1c0c1631233e00dcb459bba9355291f --- /dev/null +++ b/src/resources/application/application.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./application.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/attendance/attendance.controllers.js b/src/resources/attendance/attendance.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..2d314a47618d9cb4e9cb78b69d19aeaa7e91ed26 --- /dev/null +++ b/src/resources/attendance/attendance.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Attendance } = require('./attendance.model') + +exports.default = crudControllers(Attendance) diff --git a/src/resources/attendance/attendance.model.js b/src/resources/attendance/attendance.model.js new file mode 100644 index 0000000000000000000000000000000000000000..08bd0b4839be56b81fa9ae52828700f685fe93cf --- /dev/null +++ b/src/resources/attendance/attendance.model.js @@ -0,0 +1,31 @@ +const mongoose = require('mongoose') + +const AttendanceSchema = new mongoose.Schema( + { + activity: { + type: mongoose.Schema.Types.ObjectId, + ref: 'activity', + required: true, + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'user', + required: true, + }, + comment: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'comment', + required: true, + }, + ], + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Attendance = mongoose.model('attendance', AttendanceSchema) + +exports.Attendance = Attendance diff --git a/src/resources/attendance/attendance.router.js b/src/resources/attendance/attendance.router.js new file mode 100644 index 0000000000000000000000000000000000000000..42474e976c0bebb97a3adb1234d13f000dd339ce --- /dev/null +++ b/src/resources/attendance/attendance.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./attendance.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/comment/comment.controllers.js b/src/resources/comment/comment.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..4577b5f6871dbf3fe1c5f7f0c78cd276b15e2558 --- /dev/null +++ b/src/resources/comment/comment.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Comment } = require('./comment.model') + +exports.default = crudControllers(Comment) diff --git a/src/resources/comment/comment.model.js b/src/resources/comment/comment.model.js new file mode 100644 index 0000000000000000000000000000000000000000..3a9b22d84eefe0fb2b5b669919a9d1e77667c8bc --- /dev/null +++ b/src/resources/comment/comment.model.js @@ -0,0 +1,27 @@ +const mongoose = require('mongoose') + +const CommentSchema = new mongoose.Schema( + { + creator: { + type: mongoose.Schema.Types.ObjectId, + ref: 'user', + required: true, + }, + text: { + type: String, + required: true, + }, + date: { + type: Date, + required: true, + }, + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Comment = mongoose.model('comment', CommentSchema) + +exports.Comment = Comment diff --git a/src/resources/comment/comment.router.js b/src/resources/comment/comment.router.js new file mode 100644 index 0000000000000000000000000000000000000000..a04b49ca2119b7dc149f87a95f4dd9f7e97a0d81 --- /dev/null +++ b/src/resources/comment/comment.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./comment.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/groups/groups.controllers.js b/src/resources/groups/groups.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..a7fa91dca2ab8638cc6570e8ba3c084f0b0372d8 --- /dev/null +++ b/src/resources/groups/groups.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Groups } = require('./groups.model') + +exports.default = crudControllers(Groups) diff --git a/src/resources/groups/groups.model.js b/src/resources/groups/groups.model.js new file mode 100644 index 0000000000000000000000000000000000000000..4fa47345a87903dbff26f6c5b7c13787329e4eb9 --- /dev/null +++ b/src/resources/groups/groups.model.js @@ -0,0 +1,23 @@ +const mongoose = require('mongoose') + +const GroupsSchema = new mongoose.Schema({ + name: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + groupPath: { + type: String, + required: true, + }, +}) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Groups = mongoose.model('groups', GroupsSchema) + +exports.Groups = Groups diff --git a/src/resources/groups/groups.router.js b/src/resources/groups/groups.router.js new file mode 100644 index 0000000000000000000000000000000000000000..01f3d6ad5773a05c85d5be440cca319d3c0f3ec2 --- /dev/null +++ b/src/resources/groups/groups.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./groups.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/mentors/mentors.controllers.js b/src/resources/mentors/mentors.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..ba1487026ea10948cda4325826257bd9b4717b1f --- /dev/null +++ b/src/resources/mentors/mentors.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Mentors } = require('./mentors.model') + +exports.default = crudControllers(Mentors) diff --git a/src/resources/mentors/mentors.model.js b/src/resources/mentors/mentors.model.js new file mode 100644 index 0000000000000000000000000000000000000000..b669fdb2e2699db6597680a5c964d7707345c72d --- /dev/null +++ b/src/resources/mentors/mentors.model.js @@ -0,0 +1,20 @@ +const mongoose = require('mongoose') + +const MentorsSchema = new mongoose.Schema({ + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'user', + required: true, + }, + description: { + type: String, + required: true, + }, +}) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Mentors = mongoose.model('mentors', MentorsSchema) + +exports.Mentors = Mentors diff --git a/src/resources/mentors/mentors.router.js b/src/resources/mentors/mentors.router.js new file mode 100644 index 0000000000000000000000000000000000000000..05bcd92147ceefc52d2928a43243178e626fd379 --- /dev/null +++ b/src/resources/mentors/mentors.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./mentors.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/news/news.controllers.js b/src/resources/news/news.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..55537f6a266f9476ecd14c6ec95270499c657ecc --- /dev/null +++ b/src/resources/news/news.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { News } = require('./news.model') + +exports.default = crudControllers(News) diff --git a/src/resources/news/news.model.js b/src/resources/news/news.model.js new file mode 100644 index 0000000000000000000000000000000000000000..58e0f5d462b6a763027dab2c22de20360237e46d --- /dev/null +++ b/src/resources/news/news.model.js @@ -0,0 +1,27 @@ +const mongoose = require('mongoose') + +const NewsSchema = new mongoose.Schema( + { + title: { + type: String, + required: true, + }, + body: { + type: String, + required: true, + }, + creator: { + type: mongoose.Schema.Types.ObjectId, + ref: 'user', + required: true, + }, + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const News = mongoose.model('news', NewsSchema) + +exports.News = News diff --git a/src/resources/news/news.router.js b/src/resources/news/news.router.js new file mode 100644 index 0000000000000000000000000000000000000000..3e2af196072ce77111bd14add41d357840994094 --- /dev/null +++ b/src/resources/news/news.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./news.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/solution/solution.controllers.js b/src/resources/solution/solution.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..e8c0e56d2a6dd3f4af402395c06dcdc34e57ccee --- /dev/null +++ b/src/resources/solution/solution.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Solution } = require('./solution.model') + +exports.default = crudControllers(Solution) diff --git a/src/resources/solution/solution.model.js b/src/resources/solution/solution.model.js new file mode 100644 index 0000000000000000000000000000000000000000..cc973a356d3aa438e5070efe4ffd8aafe4b181c5 --- /dev/null +++ b/src/resources/solution/solution.model.js @@ -0,0 +1,42 @@ +const mongoose = require('mongoose') + +const SolutionSchema = new mongoose.Schema( + { + title: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + file: { + type: String, + required: true, + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'user', + required: true, + }, + comment: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'comment', + required: true, + }, + ], + isAccepted: { + type: Boolean, + required: true, + }, + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Solution = mongoose.model('solution', SolutionSchema) + +exports.Solution = Solution diff --git a/src/resources/solution/solution.router.js b/src/resources/solution/solution.router.js new file mode 100644 index 0000000000000000000000000000000000000000..3eea31136673449593a90c59f910feea952b963f --- /dev/null +++ b/src/resources/solution/solution.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./solution.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/task/task.controllers.js b/src/resources/task/task.controllers.js new file mode 100644 index 0000000000000000000000000000000000000000..0f3d2311bd9d06c436ded3f19d6e7139b5b08deb --- /dev/null +++ b/src/resources/task/task.controllers.js @@ -0,0 +1,4 @@ +const { crudControllers } = require('../../utils/crud') +const { Task } = require('./task.model') + +exports.default = crudControllers(Task) diff --git a/src/resources/task/task.model.js b/src/resources/task/task.model.js new file mode 100644 index 0000000000000000000000000000000000000000..a3141a1b3abf4e27771c55613ae0278c2693cac3 --- /dev/null +++ b/src/resources/task/task.model.js @@ -0,0 +1,34 @@ +const mongoose = require('mongoose') + +const TaskSchema = new mongoose.Schema( + { + title: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + deadline: { + type: Date, + required: true, + }, + createData: { + type: String, + required: false, + }, + bit: { + type: Number, + require: true, + }, + }, + { timestamps: true } +) + +// Careful with the docs, there are some deprecated ones +// https://mongoosejs.com/docs/guide.html + +const Task = mongoose.model('task', TaskSchema) + +exports.Task = Task diff --git a/src/resources/task/task.router.js b/src/resources/task/task.router.js new file mode 100644 index 0000000000000000000000000000000000000000..92db0c11a2e623d5f5c9b8d494d25eb021a11c8d --- /dev/null +++ b/src/resources/task/task.router.js @@ -0,0 +1,19 @@ +const { Router } = require('express') +const controllers = require('./task.controllers') + +const router = Router() + +// /api/item +router + .route('/') + .get(controllers.default.getMany) + .post(controllers.default.createOne) + +// /api/item/:id +router + .route('/:id') + .get(controllers.default.getOne) + .put(controllers.default.updateOne) + .delete(controllers.default.removeOne) + +exports.default = router diff --git a/src/resources/user/user.model.js b/src/resources/user/user.model.js index ee8c821ae927b8376665d5ec3db1637dc2ebf1a5..5264973289d838e259993fa3b3aae56aaab4a923 100644 --- a/src/resources/user/user.model.js +++ b/src/resources/user/user.model.js @@ -3,6 +3,10 @@ const isEmail = require('validator/lib/isEmail') const UserSchema = new mongoose.Schema( { + internal_id: { + type: String, + required: true, + }, schacc: { type: String, required: true, diff --git a/src/routers.js b/src/routers.js new file mode 100644 index 0000000000000000000000000000000000000000..61c09d9540f977398ddfa200fc5fc8fe9f2fea50 --- /dev/null +++ b/src/routers.js @@ -0,0 +1,23 @@ +const userRouter = require('./resources/user/user.router') +const mentorRouter = require('./resources/mentors/mentors.router') +const applicationRouter = require('./resources/application/application.router') +const newsRouter = require('./resources/news/news.router') +const groupsRouter = require('./resources/groups/groups.router') +const activityRouter = require('./resources/activity/activity.router') +const solutionRouter = require('./resources/solution/solution.router') +const commentRouter = require('./resources/comment/comment.router') +const attendanceRouter = require('./resources/attendance/attendance.router') +const taskRouter = require('./resources/task/task.router') + +exports.routers = { + userRouter: userRouter.default, + mentorRouter: mentorRouter.default, + applicationRouter: applicationRouter.default, + newsRouter: newsRouter.default, + groupsRouter: groupsRouter.default, + activityRouter: activityRouter.default, + solutionRouter: solutionRouter.default, + commentRouter: commentRouter.default, + attendanceRouter: attendanceRouter.default, + taskRouter: taskRouter.default, +} diff --git a/src/server.js b/src/server.js index 6e652d768ead36778090582307ddf8b3a15cf501..af6c13a232a7e8b07f7f059c99549956ba14da16 100644 --- a/src/server.js +++ b/src/server.js @@ -1,9 +1,13 @@ const express = require('express') const { json, urlencoded } = require('body-parser') -const config = require('./config') const cors = require('cors') const morgan = require('morgan') -const userRouter = require('./resources/user/user.router') +const passport = require('passport') +const cookieSession = require('cookie-session') + +require('dotenv').config() +require('./utils/oauth.setup') +const routers = require('./routers') const app = express() @@ -14,7 +18,50 @@ app.use(json()) app.use(urlencoded({ extended: true })) app.use(morgan('dev')) -// app.use('/api/v1', defaultProtectMiddleware) -app.use('/api/v1/user', userRouter.default) +app.use( + cookieSession({ + name: 'session', + keys: [process.env.cookieKey1, process.env.cookieKey2], + }) +) + +// Authentication +app.use(passport.initialize()) +app.use(passport.session()) + +app.get( + '/api/v1/login/authsch', + passport.authenticate('oauth2', { + scope: ['basic', 'displayName', 'mail', 'linkedAccounts'], + }) +) + +app.get( + '/api/v1/login/complete/authsch', + passport.authenticate('oauth2', { + failureRedirect: '/', // TODO failed + }), + function (req, res) { + res.redirect('/') // TODO good + } +) + +app.get('/api/v1/logout', (req, res) => { + req.session = null + req.logout() + res.redirect('/') +}) + +// API Routes +app.use('/api/v1/user', routers.routers.userRouter) +app.use('/api/v1/mentor', routers.routers.mentorRouter) +app.use('/api/v1/application', routers.routers.applicationRouter) +app.use('/api/v1/news', routers.routers.newsRouter) +app.use('/api/v1/groups', routers.routers.groupsRouter) +app.use('api/v1/solution', routers.routers.solutionRouter) +app.use('api/v1/comment', routers.routers.commentRouter) +app.use('api/v1/attendance', routers.routers.attendanceRouter) +app.use('api/v1/task', routers.routers.taskRouter) +app.use('api/v1/activity', routers.routers.activityRouter) exports.app = app diff --git a/src/utils/oauth.setup.js b/src/utils/oauth.setup.js new file mode 100644 index 0000000000000000000000000000000000000000..65f21b169e7ed1246f1f22e6d2fd37a8046c5f36 --- /dev/null +++ b/src/utils/oauth.setup.js @@ -0,0 +1,50 @@ +const passport = require('passport') +const { User } = require('../resources/user/user.model') +const Oauth2Strategy = require('passport-oauth2').Strategy +const axios = require('axios').default + +passport.serializeUser(function (user, done) { + done(null, user._id) +}) + +passport.deserializeUser(function (userId, done) { + User.findById(userId, function (err, user) { + done(err, user) + }) +}) + +const strategy = new Oauth2Strategy( + { + authorizationURL: process.env.AUTHORIZATION_URL, + tokenURL: process.env.TOKEN_URL, + clientID: process.env.CLIENT_ID, + clientSecret: process.env.CLIENT_SECRET, + callbackURL: process.env.CALLBACK_URL, + }, + async function (accessToken, refreshToken, profile, done) { + user = await User.findOne({ internal_id: profile.internal_id }) + if (!user) { + user = await User.create({ + internal_id: profile.internal_id, + schacc: profile.linkedAccounts.schacc, + fullName: profile.displayName, + secondaryEmail: profile.mail, + }) + } + return done(null, user) + } +) + +strategy.userProfile = async function (accessToken, done) { + try { + const response = await axios.get( + `https://auth.sch.bme.hu/api/profile/?access_token=${accessToken}` + ) + return done(null, response.data) + } catch (error) { + console.error(error) + // TODO error handling + } +} + +passport.use(strategy)