@@ -11,6 +11,7 @@ authRoutes.post('/register/', async (request, response) => { | |||
const email: string = request.body.email; | |||
const password: string = request.body.password; | |||
const isVerified: boolean = false; | |||
const userCollection = getDatabaseClient().db(DB_NAME).collection('users'); | |||
// Check if form is filled | |||
@@ -4,10 +4,10 @@ export interface Category { | |||
_id: string, | |||
name: string, | |||
icon: string, | |||
shelves: Array<Shelf>, | |||
shelves?: Array<Shelf>, | |||
isArchived: boolean, | |||
} | |||
export interface MongoCategory extends Omit<Category, 'shelves'> { | |||
shelves: Array<string>, // Ids | |||
shelves?: Array<string>, // Shelf IDs | |||
} |
@@ -1,16 +1,14 @@ | |||
import { LanguageType } from "./variables"; | |||
import { Word } from "./word"; | |||
export interface Library { | |||
_id: string, | |||
languageType: LanguageType, | |||
isArchived: boolean, | |||
allWords: Array<{ | |||
word: Word, | |||
isArchived: boolean, | |||
wordStats: { | |||
favouriteCount: number, // Total users who liked this word | |||
addCount: number, // Total users have added this word to their shelf | |||
} | |||
}>, | |||
allWords: Array<Word>, | |||
} | |||
export interface MongoLibrary extends Omit<Library, "allWords"> { | |||
allWords: Array<string> // Word IDs | |||
} |
@@ -1,24 +1,17 @@ | |||
import { Category } from "./category"; | |||
import { Shelf } from "./shelf"; | |||
export interface IUser { | |||
export interface User { | |||
_id: string, | |||
name: string, | |||
email: string, | |||
password: string, | |||
isVerified: boolean, | |||
otp: number, | |||
categories: Array<Category>, | |||
uncategorised: Shelf, | |||
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 | |||
export interface MongoUser extends Omit<User, "categories"> { | |||
categories?: Array<string> // Category IDs | |||
} |
@@ -1,16 +1,27 @@ | |||
import { grammarType } from "./variables"; | |||
interface gramaticalDetail { | |||
type: grammarType, | |||
description: string, | |||
examples: Array<string>, | |||
} | |||
export interface Word { | |||
_id: string, | |||
name: string, | |||
pronounciation: { | |||
text: string, | |||
audio: string, | |||
audio?: string, | |||
}, | |||
similarWords?: Array<Word>, | |||
grammaticalDetails: Array<gramaticalDetail>, | |||
wordStats: { | |||
favouriteCount: number, // Total users who liked this word | |||
addCount: number, // Total users have added this word to their shelf | |||
}, | |||
similarWords: Array<Word>, | |||
grammaticalDetails: Array<{ | |||
type: grammarType, | |||
description: string, | |||
examples: Array<string>, | |||
}> | |||
isArchived: boolean, | |||
} | |||
export interface MongoWord extends Omit<Word, "similarWords"> { | |||
similarWords: Array<string> | |||
} |
@@ -1,13 +1,13 @@ | |||
import express from 'express'; | |||
import passport from 'passport'; | |||
import { IUser } from '../models/user'; | |||
import { User } 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); | |||
const user: User = (request.user as any); | |||
// TODO: Revision logic | |||
@@ -1,17 +1,17 @@ | |||
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 passport, { use } from 'passport'; | |||
import { MongoUser } from '../models/user'; | |||
import { Category, MongoCategory } from '../models/category'; | |||
import { DB_NAME } from '../db-utils'; | |||
import { getDatabaseClient } from '../db-utils'; | |||
import { ObjectId } from 'bson'; | |||
export const userProfileRoutes = express.Router(); | |||
export const jwtAuthentication = passport.authenticate('jwt', { session: false }); | |||
userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response) => { | |||
const user: IUser = (request.user as any); | |||
const user: MongoUser = (request.user as any); | |||
response.json({ | |||
_id: user._id, | |||
name: user.name, | |||
@@ -23,21 +23,91 @@ userProfileRoutes.get('/profile/', jwtAuthentication, async (request, response) | |||
return; | |||
}); | |||
userProfileRoutes.post('/category/', jwtAuthentication, async (request, response) => { | |||
const user: IUser = (request.user as any); | |||
const user: MongoUser = (request.user as any); | |||
const userCollection = getDatabaseClient().db(DB_NAME).collection('categories'); | |||
const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories'); | |||
const userCollection = getDatabaseClient().db(DB_NAME).collection('users'); | |||
const newCategory: Category = { | |||
_id: uuidv4(), | |||
name: request.body.name, | |||
icon: request.body.icon, | |||
shelves: [], | |||
isArchived: false, | |||
if (!request.body.name || !request.body.icon) { | |||
response.status(400); | |||
response.send("Category Name or icon(base64) missing"); | |||
return; | |||
} | |||
response.status(200); | |||
try { | |||
const newCategory = await categoryCollection.insertOne({ | |||
name: request.body.name, | |||
icon: request.body.icon, | |||
isArchived: false, | |||
}); | |||
if (!user.categories) { | |||
user.categories = []; | |||
} | |||
user.categories.push(newCategory.insertedId.toHexString()); | |||
await userCollection.updateOne({ | |||
_id: user._id | |||
}, { | |||
$set: { | |||
categories: user.categories | |||
} | |||
}); | |||
response.sendStatus(200); | |||
} catch(e) { | |||
response.sendStatus(500); | |||
return; | |||
} | |||
return; | |||
}); | |||
userProfileRoutes.put('/category/', jwtAuthentication, async (request, response) => { | |||
const categoryCollection = getDatabaseClient().db(DB_NAME).collection('categories'); | |||
let currentCategory; | |||
try { | |||
currentCategory = await categoryCollection.findOne({ | |||
_id: new ObjectId(request.body._id) | |||
}); | |||
} catch { | |||
if (!currentCategory) { | |||
response.status(400); | |||
response.send("Category ID did not match"); | |||
return; | |||
} | |||
} | |||
if (request.body.isArchived) { | |||
if (typeof request.body.isArchived !== "boolean") { | |||
response.status(400); | |||
response.send("Archived should be a boolean flag"); | |||
return; | |||
} | |||
} | |||
try { | |||
await categoryCollection.updateOne({ | |||
_id: new ObjectId(request.body._id), | |||
}, { | |||
$set: { | |||
name: request.body.name ? request.body.name : currentCategory.name, | |||
icon: request.body.icon ? request.body.icon : currentCategory.icon, | |||
isArchived: request.body.isArchived !== undefined ? request.body.isArchived : currentCategory.isArchived | |||
} | |||
}); | |||
response.sendStatus(200); | |||
} catch (e) { | |||
response.status(400); | |||
response.json(e); | |||
} | |||
return; | |||
}); |