diff --git a/src/api.ts b/src/api/index.ts similarity index 75% rename from src/api.ts rename to src/api/index.ts index d36dc1f..7b0bad1 100644 --- a/src/api.ts +++ b/src/api/index.ts @@ -1,195 +1,161 @@ -import { Router } from 'express'; -import { createSessionFromCodeAndProvider } from './auth'; -import { - getGroupByID, - getPoolByID, - getPoolsWithUser, - getUserByID, -} from './data'; -import { GroupModel, PoolModel } from './models'; - -export const router = Router(); - -router.get('/user', async (req, res) => { - if (typeof req.query.userID != 'string') { - return; - } - - let userID = req.query.userID; - if (userID === '@me') { - userID = req.session.accountID; - } - - let user = await getUserByID(userID); - - if (user) { - res.json({ status: 'success', data: user }); - } else { - res.json({ status: 'error', error: 'not_found' }); - } -}); - -router.patch('/user', (req, res) => { - // if (!(req.body.userID in users)) { - // res.json({ status: 'error', error: 'user not found' }); - // } else { - // let user = users[req.body.userID]; - // user.username = req.body.username; - // user.first_name = req.body.first_name; - // user.last_name = req.body.last_name; - // res.json({ status: 'success' }); - // } -}); - -router.delete('/user', (req, res) => {}); - -router.get('/pool', async (req, res) => { - if (typeof req.query.poolID != 'string') { - return; - } - - let poolID = req.query.poolID; - let pool = await getPoolByID(poolID); - - if (pool) { - res.json({ status: 'success', data: pool }); - } else { - res.json({ status: 'error', error: 'not_found' }); - } -}); - -router.post('/pool', (req, res) => { - if (req.session.accountID == null) { - res.status(401); - return res.json({ status: 'error', error: 'need_login' }); - } - - const userID = req.session.accountID; - const { - capacity, - description, - direction, - end_time, - group_id, - start_time, - title, - type, - } = req.body; - - const pool = new PoolModel(); - Object.assign(pool, { - author_id: userID, - capacity, - description, - direction, - status: 'pending', - title, - type, - participant_ids: [], - comments: [], - create_time: new Date().toISOString(), - update_time: new Date().toISOString(), - group_id, - }); - - pool - .save() - .then((pool) => { - res.json({ status: 'success', id: pool._id }); - }) - .catch((err) => { - console.error('Error when creating a pool:', err); - res.json({ status: 'error' }); - }); -}); - -router.get('/group', async (req, res) => { - if (typeof req.query.groupID != 'string') { - return res.json({ status: 'error' }); - } - - let groupID = req.query.groupID; - let group = await getGroupByID(groupID); - - if (group) { - res.json({ status: 'success', data: group }); - } else { - res.json({ status: 'error', error: 'not_found' }); - } -}); - -router.get('/group_pools', async (req, res) => { - if (typeof req.query.groupID != 'string') { - res.json({ status: 'error', error: 'need_group_id' }); - return; - } - - let groupID = req.query.groupID; - let pools = await PoolModel.find({ group_id: groupID }).exec(); - - res.json({ status: 'success', data: pools }); -}); - -router.post('/join_pool', async (req, res) => { - if (!req.session.accountID) { - return res.json({ status: 'error', error: 'need_login' }); - } else { - let poolID = req.body.id; - let userID = req.session.accountID; - - await PoolModel.findByIdAndUpdate(poolID, { - $addToSet: { participant_ids: userID }, - }).exec(); - - res.json({ status: 'success' }); - } -}); - -router.post('/group', (req, res) => { - if (req.session.accountID == null) { - res.status(401); - return res.json({ status: 'error', error: 'need_login' }); - } - - const userID = req.session.accountID; - const name = req.body.name; - - const group = new GroupModel(); - group.set('name', name); - group.set('creator_id', userID); - group - .save() - .then((group) => { - res.json({ status: 'success', id: group._id }); - }) - .catch((err) => { - console.error('Error when creating a group:', err); - res.json({ status: 'error' }); - }); -}); - -router.get('/my_pools', async (req, res) => { - if (req.session.accountID == null) { - res.status(401); - return res.json({ status: 'error', error: 'need_login' }); - } - let pools = await getPoolsWithUser(req.session.accountID); - if (pools) { - res.json({ status: 'success', data: pools }); - } else { - res.json({ status: 'error', error: 'not_found' }); - } -}); - -router.post('/create_session', (req, res) => { - const { code, provider } = req.body; - console.log('Creating session: code =', code, 'provider =', provider); - createSessionFromCodeAndProvider(code, provider) - .then((token) => { - res.json({ status: 'success', token }); - }) - .catch((error) => { - console.error('Error when creating session:', error); - res.json({ status: 'error' }); - }); -}); +import { Router } from 'express'; +import { createSessionFromCodeAndProvider } from '../auth'; +import { getGroupByID, getPoolByID, getPoolsWithUser } from '../data'; +import { GroupModel, PoolModel } from '../models'; + +import * as user from './user'; + +export const router = Router(); + +router.use('/user', user.router); + +router.get('/pool', async (req, res) => { + if (typeof req.query.poolID != 'string') { + return; + } + + let poolID = req.query.poolID; + let pool = await getPoolByID(poolID); + + if (pool) { + res.json({ status: 'success', data: pool }); + } else { + res.json({ status: 'error', error: 'not_found' }); + } +}); + +router.post('/pool', (req, res) => { + if (req.session.accountID == null) { + res.status(401); + return res.json({ status: 'error', error: 'need_login' }); + } + + const userID = req.session.accountID; + const { + capacity, + description, + direction, + end_time, + group_id, + start_time, + title, + type, + } = req.body; + + const pool = new PoolModel(); + Object.assign(pool, { + author_id: userID, + capacity, + description, + direction, + status: 'pending', + title, + type, + participant_ids: [], + comments: [], + create_time: new Date().toISOString(), + update_time: new Date().toISOString(), + group_id, + }); + + pool + .save() + .then((pool) => { + res.json({ status: 'success', id: pool._id }); + }) + .catch((err) => { + console.error('Error when creating a pool:', err); + res.json({ status: 'error' }); + }); +}); + +router.get('/group', async (req, res) => { + if (typeof req.query.groupID != 'string') { + return res.json({ status: 'error' }); + } + + let groupID = req.query.groupID; + let group = await getGroupByID(groupID); + + if (group) { + res.json({ status: 'success', data: group }); + } else { + res.json({ status: 'error', error: 'not_found' }); + } +}); + +router.get('/group_pools', async (req, res) => { + if (typeof req.query.groupID != 'string') { + res.json({ status: 'error', error: 'need_group_id' }); + return; + } + + let groupID = req.query.groupID; + let pools = await PoolModel.find({ group_id: groupID }).exec(); + + res.json({ status: 'success', data: pools }); +}); + +router.post('/join_pool', async (req, res) => { + if (!req.session.accountID) { + return res.json({ status: 'error', error: 'need_login' }); + } else { + let poolID = req.body.id; + let userID = req.session.accountID; + + await PoolModel.findByIdAndUpdate(poolID, { + $addToSet: { participant_ids: userID }, + }).exec(); + + res.json({ status: 'success' }); + } +}); + +router.post('/group', (req, res) => { + if (req.session.accountID == null) { + res.status(401); + return res.json({ status: 'error', error: 'need_login' }); + } + + const userID = req.session.accountID; + const name = req.body.name; + + const group = new GroupModel(); + group.set('name', name); + group.set('creator_id', userID); + group + .save() + .then((group) => { + res.json({ status: 'success', id: group._id }); + }) + .catch((err) => { + console.error('Error when creating a group:', err); + res.json({ status: 'error' }); + }); +}); + +router.get('/my_pools', async (req, res) => { + if (req.session.accountID == null) { + res.status(401); + return res.json({ status: 'error', error: 'need_login' }); + } + let pools = await getPoolsWithUser(req.session.accountID); + if (pools) { + res.json({ status: 'success', data: pools }); + } else { + res.json({ status: 'error', error: 'not_found' }); + } +}); + +router.post('/create_session', (req, res) => { + const { code, provider } = req.body; + console.log('Creating session: code =', code, 'provider =', provider); + createSessionFromCodeAndProvider(code, provider) + .then((token) => { + res.json({ status: 'success', token }); + }) + .catch((error) => { + console.error('Error when creating session:', error); + res.json({ status: 'error' }); + }); +}); diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..1289572 --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,43 @@ +import { Router } from 'express'; +import { GroupModel, PoolModel, UserModel } from '../models'; +import requireApiAuth from '../requireApiAuth'; +import { ObjectID } from 'mongodb'; + +export const router = Router(); + +router.use(requireApiAuth); + +router.get('/@me/groups', async (req, res) => { + let userID = req.session.accountID; + let groups = await GroupModel.find({ + member_ids: { $all: [userID] }, + }); + + res.json({ status: 'success', data: groups }); +}); + +router.get('/@me/pools', async (req, res) => { + let userID = req.session.accountID; + let pools = await PoolModel.find({ + participant_ids: { $all: [userID] }, + }).exec(); + + res.json({ status: 'success', data: pools }); +}); + +router.get('/@me', async (req, res) => { + let user = await UserModel.findById( + new ObjectID(req.session.accountID) + ).exec(); + + res.json({ status: 'success', data: user }); +}); + +router.get('/:userID', async (req, res) => { + let userID = req.params.userID; + let user = await UserModel.findById(new ObjectID(userID)).exec(); + let data = user.toJSON(); + delete data['email']; + + res.json({ status: 'success', data }); +}); diff --git a/src/index.ts b/src/index.ts index 9a680ed..7c9c57b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,7 +16,7 @@ else console.log('DB connected successfully'); import bodyParser from 'body-parser'; import cors from 'cors'; import express from 'express'; -import * as api from './api'; +import * as api from './api/index'; import { sessionMiddleware } from './sessionMiddleware'; const app = express(); diff --git a/src/requireApiAuth.ts b/src/requireApiAuth.ts new file mode 100644 index 0000000..d621cfa --- /dev/null +++ b/src/requireApiAuth.ts @@ -0,0 +1,12 @@ +import { RequestHandler } from 'express'; + +const requireApiAuth: RequestHandler = (req, res, next) => { + if (req.session?.accountID == null) { + res.status(401); + res.json({ error: 'unauthorized' }); + } else { + next(); + } +}; + +export default requireApiAuth;