Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#147 Implementing google authentication #115

Merged
merged 4 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ const server = new ApolloServer({
let authToken = null;
let currentUser = null;
try {
authToken = req.headers.authorization;
authToken = req.headers.authorization && req.headers.authorization.startsWith("Bearer ")
? req.headers.authorization.split(" ")[1]
: req.headers.authorization;
if (authToken) {

currentUser = await findOrCreateUser(authToken);
Expand Down
5 changes: 5 additions & 0 deletions src/models/AuthUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ const userSchema = new Schema(
type: String,
enum: ["male", "female", "other"],
},
authMethod: {
type: String,
enum: ["google", "local"],
default: "local",
},
applicationPhase: {
type: String,
enum: ["Applied", "Interviewed", "Accepted", "Enrolled"],
Expand Down
43 changes: 43 additions & 0 deletions src/resolvers/loginUserResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ export const loggedUserResolvers: any = {
const role = await RoleModel.findOne({ _id: user?.role });
return role;
},
getByFilter: async (_: any, { filter }: { filter: any }) => {
const filterQuery: any = {};
for (const key in filter) {
if (filter[key] !== undefined && filter[key] !== null) {
filterQuery[key] = filter[key];
}
}
if (Object.keys(filterQuery).length === 0) {
throw new Error("No filter criteria provided.");
}
const users = await LoggedUserModel.find(filterQuery);
return users;
}
},
Mutation: {
async createUser_Logged(
Expand Down Expand Up @@ -384,6 +397,36 @@ export const loggedUserResolvers: any = {
return wasEdited;
},

async updateUserSelf(
_: any,
{ ID, editUserInput: { firstname, lastname, gender, code, country, telephone, picture } }: any, ctx: any) {

if (!ctx.currentUser) {
throw new AuthenticationError('You must be logged in');
}
if (ctx.currentUser._id.toString() !== ID) {
throw new AuthenticationError('You are only authorized to update your own account.');
}

const updateFields: any = {};
if (firstname) updateFields.firstname = firstname;
if (lastname) updateFields.lastname = lastname;
if (gender) updateFields.gender = gender;
if (code) updateFields.code = code;
if (country) updateFields.country = country;
if (telephone) updateFields.telephone = telephone;
if (picture) updateFields.picture = picture;

const wasEdited = (
await LoggedUserModel.updateOne(
{ _id: ctx.currentUser._id },
{ $set: updateFields }
)
).modifiedCount;

return wasEdited > 0;
},

assignRoleToUser: async (
_: any,
{ ID, roleID }: { ID: string; roleID: string },
Expand Down
22 changes: 22 additions & 0 deletions src/schema/loggedUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const LoggedUserSchema = gql`
picture: String
country: String
gender: String
authMethod: String
telephone: String
password: String
token: String!
Expand Down Expand Up @@ -53,6 +54,15 @@ export const LoggedUserSchema = gql`
role: String
applicationPhase: String
}
input EditUserSelfInput_Logged {
firstname: String
lastname: String
email: String
code: String
telephone: String
gender: String
country: String
}
input EditUserInput_Logged {
firstname: String
lastname: String
Expand All @@ -68,10 +78,21 @@ export const LoggedUserSchema = gql`
email: String
}

input UserFilterInput {
email: String
firstName: String
lastName: String
country: String
telephone: String
gender: String
authMethod: String
isActive: Boolean
}
type Query {
user_Logged(ID: ID!): User_Logged!
getUsers_Logged(amount: Int): [User_Logged]
checkUserRole(email: String): Role!
getByFilter(filter: UserFilterInput!): [User_Logged]!
getCohort(id: ID!): cohort
getAllCohorts: [cohort!]!
}
Expand All @@ -84,6 +105,7 @@ export const LoggedUserSchema = gql`
updateUser_Logged(ID: ID!, editUserInput: EditUserInput_Logged): Boolean
assignRoleToUser(ID: ID!, roleID: ID!): User_Logged
updateUserStatus(ID: ID!): Boolean
updateUserSelf(ID: ID!, editUserInput: EditUserSelfInput_Logged): Boolean
updateApplicationPhase(userID: ID!, newPhase: String!, cohortID: ID): User_Logged
}
`;
17 changes: 13 additions & 4 deletions src/utils/controllers/userController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const findOrCreateUser = async (token: any) => {
}
}
const googleUser = await verifyAuthToken(token);
//check existance of user
user = await checkIfUserExists(googleUser?.email);

return user ? user : createNewUser(googleUser);
Expand All @@ -37,7 +36,7 @@ const checkIfUserExists = async (email: any) =>
await LoggedUserModel.findOne({ email }).exec();

const createNewUser = async (googleUser: any) => {
const { given_name, family_name, email, picture, isActive } = googleUser;
const { given_name, family_name, email, picture } = googleUser;
const superAdminEmail = process.env.SUPER_ADMIN_EMAIL;
const adminEmail = process.env.ADMIN_EMAIL;
const applicantRole = await RoleModel.findOne({ roleName: 'applicant' });
Expand Down Expand Up @@ -78,15 +77,25 @@ const createNewUser = async (googleUser: any) => {
? adminRole?._id || createAdminRole()
: applicantRole?._id || createApplicantRole();

// Fallback values for fields missing in Google data
const user = {
firstname: given_name,
lastname: family_name,
email,
picture,
picture: picture || process.env.DEFAULT_AVATAR,
role: roleId,
isActive,
code: '+250',
password: 'GOOGLE_SIGN_IN',
country: '',
telephone: '',
gender: 'other',
authMethod: 'google',
isActive: true,
isVerified: false,
isEmailVerified: true,
createdAt: new Date().toISOString(),
};

const newUser = await new LoggedUserModel(user).save();
const userWithRole = await LoggedUserModel.findById(newUser._id).populate(
'role',
Expand Down