Skip to content

Commit d0413d0

Browse files
authored
trainee-stats-ttl (#439)
1 parent 0812f0a commit d0413d0

File tree

3 files changed

+96
-63
lines changed

3 files changed

+96
-63
lines changed

src/resolvers/profileResolver.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { sendEmail } from '../utils/sendEmail'
77
import Cohort from '../models/cohort.model'
88
import Team from '../models/team.model'
99
import mongoose, { ObjectId } from 'mongoose'
10+
import { fetchTraineeAttendance } from './attendance.resolvers'
11+
import Ticket from '../models/ticket.model'
1012

1113
const profileResolvers: any = {
1214
Query: {
@@ -163,7 +165,23 @@ const profileResolvers: any = {
163165
})
164166
.exec()
165167

166-
return traineesInSameTeam
168+
const traineeWithAttendance = await Promise.all(
169+
traineesInSameTeam.map(async (trainee) => {
170+
const objectId = new mongoose.Types.ObjectId(trainee.id)
171+
const traineeTickets = await Ticket.find({
172+
assignee: objectId,
173+
status: 'open',
174+
})
175+
const { allPhasesAverage } = await fetchTraineeAttendance(trainee.id)
176+
return {
177+
traineeInfo: trainee,
178+
attendance: allPhasesAverage,
179+
numOfTickets: traineeTickets.length,
180+
}
181+
})
182+
)
183+
184+
return traineeWithAttendance
167185
},
168186
},
169187
Profile: {

src/resolvers/userResolver.ts

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import { EmailPattern } from '../utils/validation.utils'
3737
import { Context } from './../context'
3838
import { UserInputError } from 'apollo-server'
3939
import { encodeOtpToToken, generateOtp } from '../utils/2WayAuthentication'
40-
import jwt from 'jsonwebtoken'
40+
import jwt from 'jsonwebtoken'
4141
import nonTraineeTemplate from '../utils/templates/nonTraineeTemplate'
4242
const octokit = new Octokit({ auth: `${process.env.Org_Repo_Access}` })
4343

@@ -115,7 +115,7 @@ export async function loginsCount(organizationName: any, recentLocation: any) {
115115
const resolvers: any = {
116116
Query: {
117117
async getOrganizations(_: any, __: any, context: Context) {
118-
; (await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
118+
;(await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
119119

120120
return Organization.find()
121121
},
@@ -169,7 +169,7 @@ const resolvers: any = {
169169
{ organisation, username }: any,
170170
context: Context
171171
) {
172-
; (await checkUserLoggedIn(context))([
172+
;(await checkUserLoggedIn(context))([
173173
RoleOfUser.ADMIN,
174174
RoleOfUser.COORDINATOR,
175175
'trainee',
@@ -181,7 +181,7 @@ const resolvers: any = {
181181
name: organisation,
182182
})
183183
if (!organisationExists)
184-
throw new Error('This Organization doesn\'t exist')
184+
throw new Error("This Organization doesn't exist")
185185

186186
organisation = organisationExists.gitHubOrganisation
187187

@@ -329,9 +329,16 @@ const resolvers: any = {
329329
invitation.status = 'accepted'
330330
await invitation.save()
331331
}
332-
if(user.role !=='trainee'){
333-
const content = nonTraineeTemplate( user.email,password,org.name)
334-
sendEmail(user.email,'Login Details',content,process.env.FRONTEND_LINK, process.env.ADMIN_EMAIL, process.env.ADMIN_PASS)
332+
if (user.role !== 'trainee') {
333+
const content = nonTraineeTemplate(user.email, password, org.name)
334+
sendEmail(
335+
user.email,
336+
'Login Details',
337+
content,
338+
process.env.FRONTEND_LINK,
339+
process.env.ADMIN_EMAIL,
340+
process.env.ADMIN_PASS
341+
)
335342
}
336343

337344
const newProfile = await Profile.create({
@@ -377,14 +384,14 @@ const resolvers: any = {
377384
context: any
378385
) {
379386
// Check organization validity
380-
const org = await checkLoggedInOrganization(orgToken);
381-
const { clientIpAdress } = context;
387+
const org = await checkLoggedInOrganization(orgToken)
388+
const { clientIpAdress } = context
382389
if (!org) {
383390
throw new GraphQLError('Organization not found', {
384391
extensions: { code: 'InvalidOrganization' },
385-
});
392+
})
386393
}
387-
394+
388395
// Find user with populated fields
389396
const user: any = await User.findOne({ email }).populate({
390397
path: 'cohort',
@@ -400,30 +407,30 @@ const resolvers: any = {
400407
strictPopulate: false,
401408
},
402409
},
403-
});
404-
410+
})
411+
405412
// Check if user exists
406413
if (!user) {
407414
throw new GraphQLError('Invalid credentials', {
408415
extensions: { code: 'AccountNotFound' },
409-
});
416+
})
410417
}
411-
418+
412419
// Check if account is active
413420
if (user.status?.status !== 'active') {
414421
throw new GraphQLError(
415422
`Account is ${user.status?.status}. Contact admin.`,
416423
{
417424
extensions: { code: 'AccountInactive' },
418425
}
419-
);
426+
)
420427
}
421-
428+
422429
// Check if two-factor authentication is enabled
423430
if (user.twoFactorAuth) {
424-
const otp = generateOtp(); // Generate OTP
425-
const TwoWayVerificationToken = encodeOtpToToken(otp, email); // Encode OTP
426-
431+
const otp = generateOtp() // Generate OTP
432+
const TwoWayVerificationToken = encodeOtpToToken(otp, email) // Encode OTP
433+
427434
// Send email with OTP
428435
await sendEmail(
429436
email,
@@ -432,55 +439,55 @@ const resolvers: any = {
432439
null,
433440
process.env.ADMIN_EMAIL,
434441
process.env.ADMIN_PASS
435-
);
436-
442+
)
443+
437444
// Save the Two-Way Verification Token to the database
438-
user.TwoWayVerificationToken = TwoWayVerificationToken;
439-
await user.save();
440-
445+
user.TwoWayVerificationToken = TwoWayVerificationToken
446+
await user.save()
447+
441448
// Return a response without exposing the token
442449
return {
443450
message: 'Check your email for the OTP code.',
444451
otpRequired: true,
445452
user: { id: user._id },
446-
};
453+
}
447454
} else {
448455
// Verify password if 2FA is not enabled
449-
const passwordMatch = await user?.checkPass(password);
456+
const passwordMatch = await user?.checkPass(password)
450457
if (!passwordMatch) {
451458
throw new GraphQLError('Invalid credentials', {
452459
extensions: { code: 'InvalidCredential' },
453-
});
460+
})
454461
}
455-
462+
456463
// Generate token for authenticated user
457464
const token = jwt.sign(
458465
{ userId: user._id, role: user._doc?.role || 'user' },
459466
SECRET,
460467
{ expiresIn: '2h' }
461-
);
462-
463-
const geoData = await logGeoActivity(user, clientIpAdress); // Log activity
464-
465-
const organizationName = user.organizations[0];
468+
)
469+
470+
const geoData = await logGeoActivity(user, clientIpAdress) // Log activity
471+
472+
const organizationName = user.organizations[0]
466473
if (organizationName) {
467474
const location =
468475
geoData && geoData.city && geoData.country_name
469476
? `${geoData.city}-${geoData.country_name}`
470-
: null;
471-
await loginsCount(organizationName, location);
477+
: null
478+
await loginsCount(organizationName, location)
472479
}
473-
480+
474481
// Return token and user data
475482
return {
476483
token,
477484
user: user.toJSON(),
478485
geoData,
479486
otpRequired: false,
480-
};
487+
}
481488
}
482489
},
483-
490+
484491
async deleteUser(_: any, { input }: any, context: { userId: any }) {
485492
const requester = await User.findById(context.userId)
486493
if (!requester) {
@@ -563,9 +570,9 @@ const resolvers: any = {
563570
]
564571
const org = await checkLoggedInOrganization(orgToken)
565572
const roleExists = allRoles.includes(name)
566-
if (!roleExists) throw new Error('This role doesn\'t exist')
573+
if (!roleExists) throw new Error("This role doesn't exist")
567574
const userExists = await User.findById(id)
568-
if (!userExists) throw new Error('User doesn\'t exist')
575+
if (!userExists) throw new Error("User doesn't exist")
569576

570577
const getAllUsers = await User.find({
571578
role: RoleOfUser.ADMIN,
@@ -802,7 +809,7 @@ const resolvers: any = {
802809
context: Context
803810
) {
804811
// check if requester is super admin
805-
; (await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
812+
;(await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
806813
const orgExists = await Organization.findOne({ name: name })
807814
if (action == 'approve') {
808815
if (!orgExists) {
@@ -872,7 +879,7 @@ const resolvers: any = {
872879
context: Context
873880
) {
874881
// the below commented line help to know if the user is an superAdmin to perform an action of creating an organization
875-
; (await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
882+
;(await checkUserLoggedIn(context))([RoleOfUser.SUPER_ADMIN])
876883
if (action == 'new') {
877884
const orgExists = await Organization.findOne({ name: name })
878885
if (orgExists) {
@@ -937,7 +944,7 @@ const resolvers: any = {
937944
{ name, gitHubOrganisation }: any,
938945
context: Context
939946
) {
940-
; (await checkUserLoggedIn(context))([
947+
;(await checkUserLoggedIn(context))([
941948
RoleOfUser.ADMIN,
942949
RoleOfUser.SUPER_ADMIN,
943950
])
@@ -1030,15 +1037,15 @@ const resolvers: any = {
10301037
},
10311038

10321039
async deleteOrganization(_: any, { id }: any, context: Context) {
1033-
; (await checkUserLoggedIn(context))([
1040+
;(await checkUserLoggedIn(context))([
10341041
RoleOfUser.ADMIN,
10351042
RoleOfUser.SUPER_ADMIN,
10361043
])
10371044

10381045
const organizationExists = await Organization.findOne({ _id: id })
10391046

10401047
if (!organizationExists)
1041-
throw new Error('This Organization doesn\'t exist')
1048+
throw new Error("This Organization doesn't exist")
10421049
await Cohort.deleteMany({ organization: id })
10431050
await Team.deleteMany({ organization: id })
10441051
await Phase.deleteMany({ organization: id })
@@ -1116,7 +1123,7 @@ const resolvers: any = {
11161123
if (password === confirmPassword) {
11171124
const user: any = await User.findOne({ email })
11181125
if (!user) {
1119-
throw new Error('User doesn\'t exist! ')
1126+
throw new Error("User doesn't exist! ")
11201127
}
11211128
user.password = password
11221129
await user.save()
@@ -1136,7 +1143,7 @@ const resolvers: any = {
11361143
if (newPassword === confirmPassword) {
11371144
const user: any = await User.findById(userId)
11381145
if (!user) {
1139-
throw new Error('User doesn\'t exist! ')
1146+
throw new Error("User doesn't exist! ")
11401147
}
11411148

11421149
if (bcrypt.compareSync(currentPassword, user.password)) {

src/schema/index.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ const Schema = gql`
8080
emailNotifications: Boolean!
8181
status: StatusType
8282
ratings: [Rating]
83-
twoFactorAuth:Boolean!
84-
TwoWayVerificationToken:String
83+
twoFactorAuth: Boolean!
84+
TwoWayVerificationToken: String
8585
}
8686
input RegisterInput {
8787
email: String!
@@ -149,16 +149,15 @@ const Schema = gql`
149149
user: User
150150
}
151151
type LoginResponse {
152-
token: String!
153-
user: User!
154-
message: String!
155-
}
152+
token: String!
153+
user: User!
154+
message: String!
155+
}
156156
type Login {
157157
token: String
158158
user: User
159-
message:String
160-
otpRequired:Boolean
161-
159+
message: String
160+
otpRequired: Boolean
162161
}
163162
type OrgLogin {
164163
token: String
@@ -192,7 +191,7 @@ const Schema = gql`
192191
description: String
193192
}
194193
195-
type Rating {
194+
type Rating {
196195
id: ID!
197196
user: User!
198197
sprint: Int!
@@ -271,10 +270,16 @@ const Schema = gql`
271270
createdAt: String
272271
}
273272
273+
type TTLTrainee {
274+
traineeInfo: User
275+
attendance: String
276+
numOfTickets: Int
277+
}
278+
274279
type Query {
275280
getAllUsers(orgToken: String): [User]
276281
getAllTTLUsers(orgToken: String): [User]
277-
getTTLTrainees(orgToken: String): [User]
282+
getTTLTrainees(orgToken: String): [TTLTrainee]
278283
getUsers(orgToken: String): [User]
279284
getAllCoordinators(orgToken: String): [User]
280285
getProfile: Profile
@@ -314,10 +319,13 @@ const Schema = gql`
314319
}
315320
316321
type Mutation {
317-
enableTwoFactorAuth(email: String!): String
322+
enableTwoFactorAuth(email: String!): String
318323
# //TwoWayVerificationToken: String!
319-
disableTwoFactorAuth(email: String!): String
320-
loginWithTwoFactorAuthentication(email: String!, otp: String!): LoginResponse!
324+
disableTwoFactorAuth(email: String!): String
325+
loginWithTwoFactorAuthentication(
326+
email: String!
327+
otp: String!
328+
): LoginResponse!
321329
createUserRole(name: String!): UserRole!
322330
uploadResume(userId: ID!, resume: String!): Profile
323331
dropTTLUser(email: String!, reason: String!): String!

0 commit comments

Comments
 (0)