import 'reflect-metadata'; import { Request, Response } from 'express'; import validation from 'express-joi-validation'; import { inject } from 'inversify'; import { controller, httpDelete, httpGet, httpPost } from 'inversify-express-utils'; import Joi from 'joi'; import uuidv4 from 'uuid/v4'; import COOKIES from '../constants/cookies'; import TYPES from '../constants/types'; import User from '../model/user'; import Store from '../store/store'; import { getUrl } from './../utils/config'; const validator = validation({}); const postSchema: Joi.Schema = Joi.object({ display_name: Joi.string() .optional() .alphanum(), email: Joi.string() .required() .email(), password: Joi.string().required(), }); const getSchema: Joi.Schema = Joi.object({ user_id: Joi.string().required(), }); const deleteSchema = getSchema; @controller('') export default class UserController { constructor(@inject(TYPES.UserStore) private store: Store) {} /** * Should only be used for testing - doesn't exist in real API */ @httpPost('/signup', validator.body(postSchema)) public createUser(req: Request, res: Response): void { const userId = uuidv4(); res .status(201) .cookie(COOKIES.SpotifyAccount, userId, { httpOnly: true }) .send( this.store.save({ display_name: req.body.display_name ? req.body.display_name : userId, email: req.body.email, href: `${getUrl()}/v1/users/${userId}`, id: userId, password: req.body.password, type: 'user', uri: `spotify:user:${userId}`, }), ); } /** * Should only be used for testing - doesn't exist in real API */ @httpGet('/v1/users') public getUsers(req: Request, res: Response): void { res.status(200).send({ users: this.store.getAll() }); } @httpGet('/v1/users/:user_id', validator.params(getSchema)) public getUser(req: Request, res: Response): void { const user = this.store.get(req.params.user_id); if (!user) { res.status(404).send({ error: { status: 404, message: 'No such user', }, }); return; } res.status(200).send({ display_name: user.display_name, external_urls: user.external_urls, followers: user.followers, href: user.href, id: user.id, images: user.images, type: user.type, uri: user.uri, }); } /** * Should only be used for testing - doesn't exist in real API */ @httpDelete('/v1/users/:user_id', validator.params(deleteSchema)) public deleteUser(req: Request, res: Response): void { const removed = this.store.delete(req.params.user_id); if (removed) { res.sendStatus(204); } else { res.status(404).send({ error: { status: 404, message: 'No such user', }, }); } } }