Skip to content

Commit

Permalink
#147 Implementing google authentication (#115)
Browse files Browse the repository at this point in the history
* fixing google authentication issues and creating some useful mutations

* adding search by filter querry and further authentication rules

* adding functionalities to the created resolvers
  • Loading branch information
kennyg37 authored Oct 14, 2024
1 parent d225c37 commit c5851b7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 5 deletions.
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

0 comments on commit c5851b7

Please sign in to comment.