Skip to content

Commit

Permalink
create username and calendarId cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
prakashchoudhary07 committed Aug 24, 2023
1 parent c866309 commit 0018491
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 83 deletions.
64 changes: 40 additions & 24 deletions controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,44 @@ import { NextFunction, Request, Response } from 'express';
import logger from '../utils/logger';
import * as authService from '../services/authService';
import { apiResponse } from '../@types/apiReponse';
import { Users } from '@prisma/client';

const COOKIE_CALENDAR_ID = 'calendar_id';
const COOKIE_USERNAME = 'username';

/**
*
* Sets cookies for
* @param res {Object}
* @param user {Users & { calendarId: number }}
*/
const setCookies = (
res: Response,
user: Users & { calendarId: number }
): void => {
const COOKIE_OPTIONS: any = {
domain: config.get('userAccessToken.cookieDomain'),
expires: new Date(Date.now() + config.get('userAccessToken.ttl') * 1000),
httpOnly: true,
secure: true,
sameSite: 'lax',
};

const token = authService.generateAuthToken({ userId: user.id });

res.cookie(config.get('userAccessToken.cookieName'), token, COOKIE_OPTIONS);
res.cookie(COOKIE_CALENDAR_ID, user.calendarId, {
...COOKIE_OPTIONS,
httpOnly: false,
});
res.cookie(COOKIE_USERNAME, user.username ?? '', {
...COOKIE_OPTIONS,
httpOnly: false,
});
};

/**
* Makes authentication call to google statergy
* Makes authentication call to google strategy
*
* @param req {Object} - Express request object
* @param res {Object} - Express response object
Expand Down Expand Up @@ -54,20 +89,10 @@ const googleAuthCallback = (
return res.boom(Boom.unauthorized('User cannot be authenticated'));
}

const userData = await authService.loginOrSignupWithGoogle(user._json);

const token = authService.generateAuthToken({ userId: userData?.id });
const data = await authService.loginOrSignupWithGoogle(user._json);

// respond with a cookie
res.cookie(config.get('userAccessToken.cookieName'), token, {
domain: config.get('userAccessToken.cookieDomain'),
expires: new Date(
Date.now() + config.get('userAccessToken.ttl') * 1000
),
httpOnly: true,
secure: true,
sameSite: 'lax',
});
setCookies(res, data);

return res.redirect(rCalUiUrl.href);
})(req, res, next);
Expand All @@ -92,19 +117,10 @@ const microsoftAuthCallback = (
logger.error(err);
return res.boom(Boom.unauthorized('User cannot be authenticated'));
}
const userData = await authService.loginOrSignupWithMicrosoft(user._json);
const token = authService.generateAuthToken({ userId: userData?.id });
const data = await authService.loginOrSignupWithMicrosoft(user._json);

// respond with a cookie
res.cookie(config.get('userAccessToken.cookieName'), token, {
domain: config.get('userAccessToken.cookieDomain'),
expires: new Date(
Date.now() + config.get('userAccessToken.ttl') * 1000
),
httpOnly: true,
secure: true,
sameSite: 'lax',
});
setCookies(res, data);

return res.redirect(rCalUiUrl.href);
})(req, res, next);
Expand Down
156 changes: 97 additions & 59 deletions services/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import jwt from 'jsonwebtoken';
import { GoogleOAuthJson, MicrosoftOAuthJson } from '../@types/providers';
import prisma from '../prisma/prisma';
import { jwtPayload } from '../@types/services';
import { Users } from '@prisma/client';
import { Calendar, Users } from '@prisma/client';

/**
* Generates the JWT
Expand Down Expand Up @@ -39,47 +39,107 @@ const decodeAuthToken = (token: string): any => {
return jwt.decode(token);
};

/**
*
* Returns user details with calendarId
* @param email string
* @returns Promise<Users & { calendarId: number }
*/
const getUserData = async (
email: string
): Promise<Users & { calendarId: number }> => {
const user = await prisma.users.findUniqueOrThrow({
where: {
email,
},
include: {
Calendar: {
where: {
isDeleted: false,
isPrimary: true,
},
select: {
id: true,
},
},
},
});
return { ...user, calendarId: user.Calendar[0].id };
};

/**
*
* Creates new user in DB
* @param user GoogleOAuthJson | MicrosoftOAuthJson
* @returns Promise<{ user: Users; calendar: Calendar }
*/
const createNewUser = async (
user: GoogleOAuthJson | MicrosoftOAuthJson
): Promise<{ user: Users; calendar: Calendar }> => {
let createdUser: Users | undefined;

if ('email' in user) {
logger.info(
`User with email ${user.email} does not exist. Creating new account from Google`
);
createdUser = await prisma.users.create({
data: {
email: user.email,
firstname: user.given_name,
lastname: user.family_name,
emailVerified: true,
googleProfileId: user?.sub,
},
});
} else if ('mail' in user) {
logger.info(
`User with email ${user.mail} does not exist. Creating new account from Microsoft`
);
createdUser = await prisma.users.create({
data: {
email: user.mail ?? user.userPrincipalName,
firstname: user.givenName,
lastname: user.surname,
emailVerified: true,
microsoftProfileId: user.id,
},
});
}

if (!createdUser) {
throw new Error('Failed to create user');
}

logger.info(`Creating users default calender.`);

const createdCalendar = await prisma.calendar.create({
data: {
name: createdUser.email,
ownerId: createdUser.id,
isPrimary: true,
},
});

return { user: createdUser, calendar: createdCalendar };
};

/**
* Login or signUp with Google
* @param googleProfile{Object} : Google profile response from Google OAuth2.0
*/
const loginOrSignupWithGoogle = async (
googleProfile: GoogleOAuthJson
): Promise<Users> => {
): Promise<Users & { calendarId: number }> => {
try {
const user = await prisma.users.findUnique({
where: {
email: googleProfile?.email,
},
});
const user = await getUserData(googleProfile.email);

if (user) {
return user;
} else {
logger.info(
`User with email ${googleProfile?.email} does not exist. Creating new account.`
);
const createdUser = await prisma.users.create({
data: {
email: googleProfile?.email,
firstname: googleProfile?.given_name,
lastname: googleProfile?.family_name,
emailVerified: true,
googleProfileId: googleProfile?.sub,
},
});

logger.info(`Creating users default calender.`);
const { user: createdUser, calendar: createdCalendar } =
await createNewUser(googleProfile);

await prisma.calendar.create({
data: {
name: createdUser.email,
ownerId: createdUser.id,
isPrimary: true,
},
});

return createdUser;
return { ...createdUser, calendarId: createdCalendar.id };
}
} catch (err: any) {
logger.error('loginOrSignupWithGoogle:: Error in authenticating user', {
Expand All @@ -96,41 +156,19 @@ const loginOrSignupWithGoogle = async (
*/
const loginOrSignupWithMicrosoft = async (
microsoftProfile: MicrosoftOAuthJson
): Promise<Users> => {
): Promise<Users & { calendarId: number }> => {
try {
const user = await prisma.users.findUnique({
where: {
email: microsoftProfile.mail ?? microsoftProfile?.userPrincipalName,
},
});
const user = await getUserData(
microsoftProfile.mail ?? microsoftProfile?.userPrincipalName
);

if (user) {
return user;
} else {
logger.info(
`User with email ${microsoftProfile?.userPrincipalName} does not exist. Creating new account.`
);
const createdUser = await prisma.users.create({
data: {
email: microsoftProfile.mail ?? microsoftProfile?.userPrincipalName,
firstname: microsoftProfile?.givenName,
lastname: microsoftProfile?.surname,
emailVerified: true,
microsoftProfileId: microsoftProfile?.id,
},
});

logger.info(`Creating users default calender.`);

await prisma.calendar.create({
data: {
name: createdUser.email,
ownerId: createdUser.id,
isPrimary: true,
},
});
const { user: createdUser, calendar: createdCalendar } =
await createNewUser(microsoftProfile);

return createdUser;
return { ...createdUser, calendarId: createdCalendar.id };
}
} catch (err: any) {
logger.error('loginOrSignupWithGoogle:: Error in authenticating user', {
Expand Down

0 comments on commit 0018491

Please sign in to comment.