import 'reflect-metadata'; import { Request, Response } from 'express'; import validation from 'express-joi-validation'; import { inject } from 'inversify'; import { controller, httpGet } from 'inversify-express-utils'; import * as Joi from 'joi'; import uuidv4 from 'uuid/v4'; import COOKIES from '../constants/cookies'; import TYPES from '../constants/types'; import Token from '../model/token'; import User from '../model/user'; import Store from '../store/store'; const validator = validation({}); const getParamsSchema: Joi.Schema = Joi.object({ client_id: Joi.string().required(), redirect_uri: Joi.string().required(), scope: Joi.string().optional(), response_type: Joi.string().valid('token'), }); @controller('') export default class AuthorizeController { constructor( @inject(TYPES.TokenStore) private store: Store, @inject(TYPES.UserStore) private userStore: Store, ) {} @httpGet('/authorize', validator.query(getParamsSchema)) public authorize(req: Request, res: Response): void { const clientUserId = req.cookies ? req.cookies[COOKIES.SpotifyAccount] : undefined; const clientUser = clientUserId ? this.userStore.get(clientUserId) : undefined; if (!clientUser) { res.status(400).send(`Unable to get user from cookie ${COOKIES.SpotifyAccount}`); return; } const now = new Date(); const token: Token = new Token({ token: Buffer.from(uuidv4()).toString('base64'), type: 'Bearer', scope: req.params.scope ? req.params.scope.split(' ') : undefined, expiryDate: new Date(now.getTime() + 3600 * 1000), userId: clientUser.id, }); this.store.save(token); res.redirect( `${req.query.redirect_uri}#access_token=${token.token}` + `&token_type=${token.type}&expires_in=${token.getTimeToLiveInSeconds()}`, ); } }