@@ -1,5 +1,5 @@ | |||||
{ | { | ||||
"name": "job-portal", | |||||
"name": "anamnesis", | |||||
"version": "1.0.0", | "version": "1.0.0", | ||||
"lockfileVersion": 1, | "lockfileVersion": 1, | ||||
"requires": true, | "requires": true, | ||||
@@ -30,6 +30,19 @@ | |||||
"js-tokens": "^4.0.0" | "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": { | "@mapbox/node-pre-gyp": { | ||||
"version": "1.0.5", | "version": "1.0.5", | ||||
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", | "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" | "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": { | "@types/bcrypt": { | ||||
"version": "5.0.0", | "version": "5.0.0", | ||||
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", | "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", | ||||
@@ -266,6 +299,16 @@ | |||||
"negotiator": "0.6.2" | "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": { | "agent-base": { | ||||
"version": "6.0.2", | "version": "6.0.2", | ||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", | ||||
@@ -346,6 +389,11 @@ | |||||
"readable-stream": "^2.0.6" | "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": { | "argparse": { | ||||
"version": "1.0.10", | "version": "1.0.10", | ||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", | ||||
@@ -688,6 +736,11 @@ | |||||
"vary": "^1" | "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": { | "crypto-random-string": { | ||||
"version": "2.0.0", | "version": "2.0.0", | ||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", | ||||
@@ -752,8 +805,7 @@ | |||||
"diff": { | "diff": { | ||||
"version": "4.0.2", | "version": "4.0.2", | ||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", | "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": { | "dot-prop": { | ||||
"version": "5.3.0", | "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": { | "media-typer": { | ||||
"version": "0.3.0", | "version": "0.3.0", | ||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", | ||||
@@ -2068,6 +2125,25 @@ | |||||
"punycode": "^2.1.1" | "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": { | "tslib": { | ||||
"version": "1.14.1", | "version": "1.14.1", | ||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | ||||
@@ -2325,6 +2401,11 @@ | |||||
"version": "4.0.0", | "version": "4.0.0", | ||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", | ||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" | "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", | "nodemon": "^2.0.12", | ||||
"passport": "^0.5.0", | "passport": "^0.5.0", | ||||
"passport-jwt": "^4.0.0", | "passport-jwt": "^4.0.0", | ||||
"ts-node": "^10.3.0", | |||||
"uuid": "^8.3.2" | "uuid": "^8.3.2" | ||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
@@ -3,27 +3,14 @@ import { DB_NAME, getDatabaseClient } from '../db-utils'; | |||||
import bcrypt from 'bcrypt'; | import bcrypt from 'bcrypt'; | ||||
import { generateJWT, SALT_ROUNDS } from './auth'; | import { generateJWT, SALT_ROUNDS } from './auth'; | ||||
import sendGridMail, { MailDataRequired } from '@sendgrid/mail'; | 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(); | const authRoutes = express.Router(); | ||||
authRoutes.post('/register-applicant/', async (request, response) => { | |||||
authRoutes.post('/register/', async (request, response) => { | |||||
const name: string = request.body.name; | const name: string = request.body.name; | ||||
const email: string = request.body.email; | const email: string = request.body.email; | ||||
const password: string = request.body.password; | const password: string = request.body.password; | ||||
const isVerified: boolean = false; | 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'); | const userCollection = getDatabaseClient().db(DB_NAME).collection('users'); | ||||
// Check if form is filled | // Check if form is filled | ||||
@@ -59,8 +46,6 @@ authRoutes.post('/register-applicant/', async (request, response) => { | |||||
email, | email, | ||||
password: hashedPassword, | password: hashedPassword, | ||||
isVerified, | isVerified, | ||||
categories, | |||||
uncategorised | |||||
}); | }); | ||||
}); | }); | ||||
@@ -180,9 +165,8 @@ authRoutes.post('/verify-user/', async (request, response) => { | |||||
authRoutes.post('/api-auth/', async (request, response) => { | authRoutes.post('/api-auth/', async (request, response) => { | ||||
const email: string = request.body.email; | const email: string = request.body.email; | ||||
const password: string = request.body.password; | const password: string = request.body.password; | ||||
const userType: string = request.body.userType; | |||||
if (!email || !password || !userType) { | |||||
if (!email || !password) { | |||||
response.status(400); | response.status(400); | ||||
response.send("Please field the required fields"); | response.send("Please field the required fields"); | ||||
return; | return; | ||||
@@ -192,7 +176,6 @@ authRoutes.post('/api-auth/', async (request, response) => { | |||||
let users = await userCollection.find({ | let users = await userCollection.find({ | ||||
email, | email, | ||||
userType, | |||||
}).toArray(); | }).toArray(); | ||||
const matchedUser = users[0]; | const matchedUser = users[0]; | ||||
@@ -5,6 +5,7 @@ import authRoutes from './authentication/routes'; | |||||
import { connectToDatabaseServer } from './db-utils'; | import { connectToDatabaseServer } from './db-utils'; | ||||
import sendGridMail from '@sendgrid/mail'; | import sendGridMail from '@sendgrid/mail'; | ||||
import { userProfileRoutes } from './user-profile/routes'; | import { userProfileRoutes } from './user-profile/routes'; | ||||
import { revisionRoutes } from './revision/routes'; | |||||
const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY || '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'; | 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.set('port', process.env.PORT || 8001); | ||||
app.use('/', authRoutes); | app.use('/', authRoutes); | ||||
app.use('/', userProfileRoutes); | app.use('/', userProfileRoutes); | ||||
app.use('/', revisionRoutes); | |||||
app.get('/', (request, response) => { | app.get('/', (request, response) => { | ||||
response.send('Server running @ port' + app.get('port')); | response.send('Server running @ port' + app.get('port')); | ||||
@@ -6,4 +6,8 @@ export interface Category { | |||||
icon: string, | icon: string, | ||||
shelves: Array<Shelf>, | shelves: Array<Shelf>, | ||||
isArchived: boolean, | isArchived: boolean, | ||||
} | |||||
export interface MongoCategory extends Omit<Category, 'shelves'> { | |||||
shelves: Array<string>, // Ids | |||||
} | } |
@@ -12,6 +12,26 @@ export interface Shelf { | |||||
notes: Array<string>, | notes: Array<string>, | ||||
isFavourite: boolean, | isFavourite: boolean, | ||||
nextRevisionDateTime: Date, | 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<{ | revisionHistory : Array<{ | ||||
day: Date, | day: Date, | ||||
wasRecallSuccessful: boolean, | wasRecallSuccessful: boolean, | ||||
@@ -1,7 +1,7 @@ | |||||
import { Category } from "./category"; | import { Category } from "./category"; | ||||
import { Shelf } from "./shelf"; | import { Shelf } from "./shelf"; | ||||
export type IUser = { | |||||
export interface IUser { | |||||
_id: string, | _id: string, | ||||
name: string, | name: string, | ||||
email: string, | email: string, | ||||
@@ -10,4 +10,15 @@ export type IUser = { | |||||
otp: number, | otp: number, | ||||
categories: Array<Category>, | categories: Array<Category>, | ||||
uncategorised: Shelf, | 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 express from 'express'; | ||||
import passport from 'passport'; | import passport from 'passport'; | ||||
import { IUser } from '../models/user'; | 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(); | export const userProfileRoutes = express.Router(); | ||||
@@ -8,6 +12,32 @@ export const jwtAuthentication = passport.authenticate('jwt', { session: false } | |||||
userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response) => { | userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response) => { | ||||
const user: IUser = (request.user as any); | 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; | 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; | |||||
}); |