tutorbook
Version:
Web app connecting students with expert mentors and tutors.
68 lines (62 loc) • 2.63 kB
text/typescript
import { NextApiRequest, NextApiResponse } from 'next';
import { User, UserJSON } from '@tutorbook/model';
import { SignUpEmail } from '@tutorbook/emails';
import to from 'await-to-js';
import mail from '@sendgrid/mail';
import error from './helpers/error';
import createUser from './helpers/create-user';
import { auth, FirebaseError } from './helpers/firebase';
mail.setApiKey(process.env.SENDGRID_API_KEY as string);
export type CreateUserRes = UserJSON;
/**
* Takes the parsed results of a sign-up form (e.g. the `hero-form`) and:
* 1. Creates and signs-in a new Firebase Authentication user.
* 2. (Optional) Creates a new Firesbase Authentication user for the parents.
* 3. (Optional) Creates a new Firestore profile document for the parents.
* 4. Creates a new Firestore profile document for the given user.
* 5. Sends an email verification link to the new user (and his/her parents).
*
* Note that this endpoint **will not function** if a user with the given email
* already exists. One should use the `/api/user/update` endpoint for that.
*
* @param {User} user - The user to create (should be in JSON form).
* @param {User[]} [parents] - The parents of the given user to create (also in
* JSON form).
*
* @return {UserJSON} The create user profile in JSON form containing a custom
* Firebase Authentication login token (that can be used to log the user into
* Firebase client-side; a requirement to retrieve the user's JWT for subsequent
* API requests).
*/
export default async function createUserEndpoint(
req: NextApiRequest,
res: NextApiResponse<CreateUserRes>
): Promise<void> {
/* eslint-disable @typescript-eslint/no-unsafe-member-access, no-shadow */
if (!req.body) {
error(res, 'You must provide a request body.');
} else if (!req.body.user) {
error(res, 'Your request body must contain a user field.');
} else {
const user: User = User.fromJSON(req.body.user);
const parents: User[] = (
(req.body.parents as UserJSON[]) || []
).map((parentJSON: UserJSON) => User.fromJSON(parentJSON));
const [err] = await to(createUser(user, parents));
if (err) {
error(res, err.message, 500, err);
} else {
const [err, token] = await to<string, FirebaseError>(
auth.createCustomToken(user.id)
);
if (err) {
error(res, `${err.name} creating auth JWT: ${err.message}`, 500, err);
} else {
user.token = token;
res.status(201).json(user.toJSON());
await mail.send(new SignUpEmail(user));
}
}
}
/* eslint-enable @typescript-eslint/no-unsafe-member-access, no-shadow */
}