| @@ -1,5 +1,5 @@ | |||
| { | |||
| "name": "job-portal", | |||
| "name": "anamnesis", | |||
| "version": "1.0.0", | |||
| "lockfileVersion": 1, | |||
| "requires": true, | |||
| @@ -30,6 +30,19 @@ | |||
| "js-tokens": "^4.0.0" | |||
| } | |||
| }, | |||
| "@cspotcode/source-map-consumer": { | |||
| "version": "0.8.0", | |||
| "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", | |||
| "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" | |||
| }, | |||
| "@cspotcode/source-map-support": { | |||
| "version": "0.7.0", | |||
| "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", | |||
| "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", | |||
| "requires": { | |||
| "@cspotcode/source-map-consumer": "0.8.0" | |||
| } | |||
| }, | |||
| "@mapbox/node-pre-gyp": { | |||
| "version": "1.0.5", | |||
| "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", | |||
| @@ -103,6 +116,26 @@ | |||
| "defer-to-connect": "^1.0.1" | |||
| } | |||
| }, | |||
| "@tsconfig/node10": { | |||
| "version": "1.0.8", | |||
| "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", | |||
| "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" | |||
| }, | |||
| "@tsconfig/node12": { | |||
| "version": "1.0.9", | |||
| "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", | |||
| "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" | |||
| }, | |||
| "@tsconfig/node14": { | |||
| "version": "1.0.1", | |||
| "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", | |||
| "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" | |||
| }, | |||
| "@tsconfig/node16": { | |||
| "version": "1.0.2", | |||
| "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", | |||
| "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" | |||
| }, | |||
| "@types/bcrypt": { | |||
| "version": "5.0.0", | |||
| "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", | |||
| @@ -266,6 +299,16 @@ | |||
| "negotiator": "0.6.2" | |||
| } | |||
| }, | |||
| "acorn": { | |||
| "version": "8.5.0", | |||
| "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", | |||
| "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==" | |||
| }, | |||
| "acorn-walk": { | |||
| "version": "8.2.0", | |||
| "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", | |||
| "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" | |||
| }, | |||
| "agent-base": { | |||
| "version": "6.0.2", | |||
| "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", | |||
| @@ -346,6 +389,11 @@ | |||
| "readable-stream": "^2.0.6" | |||
| } | |||
| }, | |||
| "arg": { | |||
| "version": "4.1.3", | |||
| "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", | |||
| "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" | |||
| }, | |||
| "argparse": { | |||
| "version": "1.0.10", | |||
| "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", | |||
| @@ -688,6 +736,11 @@ | |||
| "vary": "^1" | |||
| } | |||
| }, | |||
| "create-require": { | |||
| "version": "1.1.1", | |||
| "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", | |||
| "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" | |||
| }, | |||
| "crypto-random-string": { | |||
| "version": "2.0.0", | |||
| "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", | |||
| @@ -752,8 +805,7 @@ | |||
| "diff": { | |||
| "version": "4.0.2", | |||
| "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", | |||
| "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", | |||
| "dev": true | |||
| "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" | |||
| }, | |||
| "dot-prop": { | |||
| "version": "5.3.0", | |||
| @@ -1380,6 +1432,11 @@ | |||
| } | |||
| } | |||
| }, | |||
| "make-error": { | |||
| "version": "1.3.6", | |||
| "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", | |||
| "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" | |||
| }, | |||
| "media-typer": { | |||
| "version": "0.3.0", | |||
| "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | |||
| @@ -2068,6 +2125,25 @@ | |||
| "punycode": "^2.1.1" | |||
| } | |||
| }, | |||
| "ts-node": { | |||
| "version": "10.3.0", | |||
| "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", | |||
| "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", | |||
| "requires": { | |||
| "@cspotcode/source-map-support": "0.7.0", | |||
| "@tsconfig/node10": "^1.0.7", | |||
| "@tsconfig/node12": "^1.0.7", | |||
| "@tsconfig/node14": "^1.0.0", | |||
| "@tsconfig/node16": "^1.0.2", | |||
| "acorn": "^8.4.1", | |||
| "acorn-walk": "^8.1.1", | |||
| "arg": "^4.1.0", | |||
| "create-require": "^1.1.0", | |||
| "diff": "^4.0.1", | |||
| "make-error": "^1.1.1", | |||
| "yn": "3.1.1" | |||
| } | |||
| }, | |||
| "tslib": { | |||
| "version": "1.14.1", | |||
| "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | |||
| @@ -2325,6 +2401,11 @@ | |||
| "version": "4.0.0", | |||
| "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | |||
| "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" | |||
| }, | |||
| "yn": { | |||
| "version": "3.1.1", | |||
| "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", | |||
| "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" | |||
| } | |||
| } | |||
| } | |||
| @@ -20,6 +20,7 @@ | |||
| "nodemon": "^2.0.12", | |||
| "passport": "^0.5.0", | |||
| "passport-jwt": "^4.0.0", | |||
| "ts-node": "^10.3.0", | |||
| "uuid": "^8.3.2" | |||
| }, | |||
| "devDependencies": { | |||
| @@ -3,27 +3,14 @@ import { DB_NAME, getDatabaseClient } from '../db-utils'; | |||
| import bcrypt from 'bcrypt'; | |||
| import { generateJWT, SALT_ROUNDS } from './auth'; | |||
| import sendGridMail, { MailDataRequired } from '@sendgrid/mail'; | |||
| import { Category } from '../models/category'; | |||
| import { Shelf } from '..//models/shelf'; | |||
| import { v4 as uuidv4 } from 'uuid'; | |||
| const authRoutes = express.Router(); | |||
| authRoutes.post('/register-applicant/', async (request, response) => { | |||
| authRoutes.post('/register/', async (request, response) => { | |||
| const name: string = request.body.name; | |||
| const email: string = request.body.email; | |||
| const password: string = request.body.password; | |||
| const isVerified: boolean = false; | |||
| const categories: Array<Category> = []; | |||
| const uncategorised: Shelf = { | |||
| _id: uuidv4(), | |||
| name: 'Uncategorised', | |||
| description: '', | |||
| viewType: 'PRIVATE', | |||
| isArchived: false, | |||
| addedWords: [] | |||
| } | |||
| const userCollection = getDatabaseClient().db(DB_NAME).collection('users'); | |||
| // Check if form is filled | |||
| @@ -59,8 +46,6 @@ authRoutes.post('/register-applicant/', async (request, response) => { | |||
| email, | |||
| password: hashedPassword, | |||
| isVerified, | |||
| categories, | |||
| uncategorised | |||
| }); | |||
| }); | |||
| @@ -180,9 +165,8 @@ authRoutes.post('/verify-user/', async (request, response) => { | |||
| authRoutes.post('/api-auth/', async (request, response) => { | |||
| const email: string = request.body.email; | |||
| const password: string = request.body.password; | |||
| const userType: string = request.body.userType; | |||
| if (!email || !password || !userType) { | |||
| if (!email || !password) { | |||
| response.status(400); | |||
| response.send("Please field the required fields"); | |||
| return; | |||
| @@ -192,7 +176,6 @@ authRoutes.post('/api-auth/', async (request, response) => { | |||
| let users = await userCollection.find({ | |||
| email, | |||
| userType, | |||
| }).toArray(); | |||
| const matchedUser = users[0]; | |||
| @@ -5,6 +5,7 @@ import authRoutes from './authentication/routes'; | |||
| import { connectToDatabaseServer } from './db-utils'; | |||
| import sendGridMail from '@sendgrid/mail'; | |||
| import { userProfileRoutes } from './user-profile/routes'; | |||
| import { revisionRoutes } from './revision/routes'; | |||
| const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY || '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'; | |||
| @@ -17,6 +18,7 @@ app.use(passport.initialize()); | |||
| app.set('port', process.env.PORT || 8001); | |||
| app.use('/', authRoutes); | |||
| app.use('/', userProfileRoutes); | |||
| app.use('/', revisionRoutes); | |||
| app.get('/', (request, response) => { | |||
| response.send('Server running @ port' + app.get('port')); | |||
| @@ -6,4 +6,8 @@ export interface Category { | |||
| icon: string, | |||
| shelves: Array<Shelf>, | |||
| isArchived: boolean, | |||
| } | |||
| export interface MongoCategory extends Omit<Category, 'shelves'> { | |||
| shelves: Array<string>, // Ids | |||
| } | |||
| @@ -12,6 +12,26 @@ export interface Shelf { | |||
| notes: Array<string>, | |||
| isFavourite: boolean, | |||
| nextRevisionDateTime: Date, | |||
| spaceBetweenRecall: number, // in Days | |||
| revisionHistory : Array<{ | |||
| day: Date, | |||
| wasRecallSuccessful: boolean, | |||
| }> | |||
| }> | |||
| } | |||
| export interface MongoShelf { | |||
| _id: string, | |||
| name: string, | |||
| description: string, | |||
| viewType: viewPermissionType, | |||
| isArchived: boolean, | |||
| addedWords: Array<{ | |||
| word: Word, | |||
| notes: Array<string>, | |||
| isFavourite: boolean, | |||
| nextRevisionDateTime: Date, | |||
| spaceBetweenRecall: number, // in Days | |||
| revisionHistory : Array<{ | |||
| day: Date, | |||
| wasRecallSuccessful: boolean, | |||
| @@ -1,7 +1,7 @@ | |||
| import { Category } from "./category"; | |||
| import { Shelf } from "./shelf"; | |||
| export type IUser = { | |||
| export interface IUser { | |||
| _id: string, | |||
| name: string, | |||
| email: string, | |||
| @@ -10,4 +10,15 @@ export type IUser = { | |||
| otp: number, | |||
| categories: Array<Category>, | |||
| uncategorised: Shelf, | |||
| } | |||
| export interface MongoIUser { | |||
| _id: string, | |||
| name: string, | |||
| email: string, | |||
| password: string, | |||
| isVerified: boolean, | |||
| otp: number, | |||
| categories: Array<string>, //Array of IDs | |||
| uncategorised: string, // Shelf ID | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| import express from 'express'; | |||
| import passport from 'passport'; | |||
| import { IUser } from '../models/user'; | |||
| export const revisionRoutes = express.Router(); | |||
| export const jwtAuthentication = passport.authenticate('jwt', { session: false }); | |||
| revisionRoutes.get('/revision-questions/', jwtAuthentication, async (request, response) => { | |||
| const user: IUser = (request.user as any); | |||
| // TODO: Revision logic | |||
| return; | |||
| }); | |||
| @@ -1,6 +1,10 @@ | |||
| import express from 'express'; | |||
| import passport from 'passport'; | |||
| import { IUser } from '../models/user'; | |||
| import { v4 as uuidv4 } from 'uuid'; | |||
| import { Category } from '../models/category'; | |||
| import { DB_NAME } from '../db-utils'; | |||
| import { getDatabaseClient } from '../db-utils'; | |||
| export const userProfileRoutes = express.Router(); | |||
| @@ -8,6 +12,32 @@ export const jwtAuthentication = passport.authenticate('jwt', { session: false } | |||
| userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response) => { | |||
| const user: IUser = (request.user as any); | |||
| response.json(user); | |||
| response.json({ | |||
| _id: user._id, | |||
| name: user.name, | |||
| email: user.email, | |||
| isVerified: user.isVerified, | |||
| categories: user.categories, | |||
| uncategorised: user.uncategorised | |||
| }); | |||
| return; | |||
| }); | |||
| }); | |||
| userProfileRoutes.post('/category/', jwtAuthentication, async (request, response) => { | |||
| const user: IUser = (request.user as any); | |||
| const userCollection = getDatabaseClient().db(DB_NAME).collection('categories'); | |||
| const newCategory: Category = { | |||
| _id: uuidv4(), | |||
| name: request.body.name, | |||
| icon: request.body.icon, | |||
| shelves: [], | |||
| isArchived: false, | |||
| } | |||
| response.status(200); | |||
| return; | |||
| }); | |||