Skip to content

Commit 9b0292e

Browse files
committed
fix seeding and helpers
1 parent c2f70ca commit 9b0292e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1626
-1903
lines changed

package-lock.json

Lines changed: 13 additions & 436 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
"@octokit/graphql": "^7.0.1",
6262
"@octokit/rest": "^19.0.13",
6363
"@types/node-cron": "^3.0.11",
64-
"apollo-server": "^3.13.0",
6564
"axios": "^1.7.7",
6665
"bcryptjs": "^2.4.3",
6766
"cloudinary": "^1.30.1",
@@ -88,7 +87,8 @@
8887
"ts-node-dev": "^2.0.0",
8988
"tslog": "^4.9.2",
9089
"ws": "^8.11.0",
91-
"xlsx": "^0.18.5"
90+
"xlsx": "^0.18.5",
91+
"zod": "^3.23.8"
9292
},
9393
"devDependencies": {
9494
"@istanbuljs/nyc-config-typescript": "^1.0.1",

src/helpers/generateRandomPassword.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ export default function generateRandomPassword(length = 8) {
44
return generator.generate({
55
length,
66
numbers: true,
7+
symbols: true,
78
});
89
}
Lines changed: 100 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,106 @@
1+
import { GraphQLError } from 'graphql'
12
import Cohort from '../models/cohort.model'
2-
import { Organization } from '../models/organization.model'
3+
import { IOrganization, Organization } from '../models/organization.model'
34
import Program from '../models/program.model'
4-
import { User } from '../models/user'
5+
import { RoleOfUser, User, UserInterface } from '../models/user'
56

6-
export default async function isAssigned(organName: string, userId: string) {
7-
// Fetch programs and populate organization
8-
const programs: any = await Program.find().populate({
9-
path: 'organization',
10-
model: Organization,
11-
strictPopulate: false,
12-
})
13-
14-
const cohorts: any = await Cohort.find().populate({
15-
path: 'program',
16-
model: Program,
17-
strictPopulate: false,
18-
populate: [
19-
{
20-
path: 'organization',
21-
model: Organization,
22-
strictPopulate: false,
23-
},
24-
{
25-
path: 'users',
26-
model: User,
27-
strictPopulate: false,
28-
},
29-
],
30-
})
31-
let isAssignedToProgramOrCohort = false
32-
33-
// Check if the user is assigned to any program associated with the organization
34-
for (const element of programs) {
35-
if (element.organization?.name === organName) {
36-
isAssignedToProgramOrCohort = true
37-
return isAssignedToProgramOrCohort
38-
}
7+
export default async function isAssignedToAnEntity(user: UserInterface, org: IOrganization) {
8+
const orgUserData = user.organizations.find(data=>data.orgId.toString()===org._id.toString())
9+
if(!orgUserData){
10+
throw new GraphQLError(`User ${user.email} is not part of ${org.name}`,{
11+
extensions:{
12+
code: "FORBIDDEN"
13+
}
14+
})
3915
}
40-
41-
// Check if the user is assigned to any cohort associated with the organization
42-
for (const cohort of cohorts) {
43-
if (cohort.program.organization?.name === organName) {
44-
if (
45-
cohort.users.some(
46-
(user: { _id: { toString: () => string } }) =>
47-
user._id.toString() === userId
48-
)
49-
) {
50-
isAssignedToProgramOrCohort = true
51-
return isAssignedToProgramOrCohort
52-
}
53-
}
16+
switch(orgUserData.role){
17+
case RoleOfUser.SUPER_ADMIN:
18+
case RoleOfUser.ADMIN:
19+
break
20+
case RoleOfUser.MANAGER:
21+
const programs = await Program.find({
22+
manager: user._id,
23+
organization: org._id,
24+
})
25+
if(!programs.length){
26+
throw new GraphQLError(`User ${user.email} does not manage any programs`,{
27+
extensions: {
28+
code: "FORBIDDEN"
29+
}
30+
})
31+
}
32+
break
33+
case RoleOfUser.COORDINATOR:
34+
// if(!orgUserData.program){
35+
// throw new GraphQLError(`User ${user.email} is not assigned to a program`,{
36+
// extensions: {
37+
// code: "FORBIDDEN"
38+
// }
39+
// })
40+
// }
41+
const cohorts = await Cohort.find({
42+
coordinator: user._id,
43+
organization: org._id,
44+
})
45+
if(!cohorts.length){
46+
throw new GraphQLError(`User ${user.email} does not manage any cohorts`,{
47+
extensions: {
48+
code: "FORBIDDEN"
49+
}
50+
})
51+
}
52+
break
53+
case RoleOfUser.TTL:
54+
if(!orgUserData.program){
55+
throw new GraphQLError(`User ${user.email} is not assigned to a program`,{
56+
extensions: {
57+
code: "FORBIDDEN"
58+
}
59+
})
60+
}
61+
if(!orgUserData.cohort){
62+
throw new GraphQLError(`User ${user.email} is not assigned to a cohort`,{
63+
extensions: {
64+
code: "FORBIDDEN"
65+
}
66+
})
67+
}
68+
if(!orgUserData.team){
69+
throw new GraphQLError(`User ${user.email} does not manage any team`,{
70+
extensions: {
71+
code: "FORBIDDEN"
72+
}
73+
})
74+
}
75+
break
76+
case RoleOfUser.TRAINEE:
77+
if(!orgUserData.program){
78+
throw new GraphQLError(`User ${user.email} is not assigned to a program`,{
79+
extensions: {
80+
code: "FORBIDDEN"
81+
}
82+
})
83+
}
84+
if(!orgUserData.cohort){
85+
throw new GraphQLError(`User ${user.email} is not assigned to a cohort`,{
86+
extensions: {
87+
code: "FORBIDDEN"
88+
}
89+
})
90+
}
91+
if(!orgUserData.team){
92+
throw new GraphQLError(`User ${user.email} is not assigned to a team`,{
93+
extensions: {
94+
code: "FORBIDDEN"
95+
}
96+
})
97+
}
98+
break
99+
default:
100+
throw new GraphQLError("User role is not valid",{
101+
extensions: {
102+
code: "FORBIDDEN"
103+
}
104+
})
54105
}
55-
return isAssignedToProgramOrCohort
56106
}

src/helpers/logintracker.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
1-
import { User } from '../models/user'
1+
import { GraphQLError } from 'graphql'
2+
import { IOrganization, Organization } from '../models/organization.model'
3+
import { OrgUserDataInterface, User, UserInterface } from '../models/user'
24
import { sendEmail } from '../utils/sendEmail'
35

4-
export const checkloginAttepmts = async (Profile: any, user: any) => {
6+
export const checkloginAttepmts = async (user: UserInterface, org: IOrganization) => {
57
try {
6-
const { activity } = await Profile.findOne({ user })
8+
const populatedUser = await user.populate({
9+
path: "organizations",
10+
populate: {
11+
path: "profile"
12+
}
13+
})
14+
const orgUserData = populatedUser.organizations.find(data=>data.orgId.toString()===org._id.toString())
15+
if(!orgUserData){
16+
throw new GraphQLError(`User ${user.email} is not part of ${org.name}`,{
17+
extensions: {
18+
code: "FORBIDDEN"
19+
}
20+
})
21+
}
22+
const { activity } = (orgUserData.profile as any)
723
if (activity && activity?.length > 1) {
824
const inline = activity[activity.length - 1]
925
const recent = Number(inline.failed) + 1 || 0
@@ -29,14 +45,16 @@ export const checkloginAttepmts = async (Profile: any, user: any) => {
2945
return 1
3046
}
3147

32-
export async function checkUserAccountStatus(
33-
userId: string
34-
): Promise<boolean | 'active' | 'drop' | 'suspended' | any> {
35-
const user = await User.findById(userId)
36-
if (!user) {
37-
return false
48+
export async function checkUserAccountStatus(user: UserInterface, org:IOrganization): Promise<'active' | 'drop' | 'suspended' | any> {
49+
const orgUserData = user.organizations.find(data=> data.orgId.toString()===org._id.toString())
50+
if(!orgUserData){
51+
throw new GraphQLError(`User ${user.email} is not part of ${org.name}`,{
52+
extensions:{
53+
code: "FORBIDDEN"
54+
}
55+
})
3856
}
39-
return user?.status?.status
57+
return orgUserData.status?.status
4058
}
4159

4260
const emailtemp = (trials: any, date: any, country: any, city: any) => {

src/helpers/organization.helper.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { GraphQLError } from 'graphql'
22
import 'dotenv/config'
33
import { JwtPayload, verify } from 'jsonwebtoken'
4-
import { Organization } from '../models/organization.model'
4+
import { IOrganization, Organization } from '../models/organization.model'
5+
import { OrgUserDataInterface, UserInterface } from '../models/user'
56

67
export async function checkLoggedInOrganization(token?: string) {
78
const SECRET = process.env.SECRET as string
@@ -27,6 +28,14 @@ export async function checkLoggedInOrganization(token?: string) {
2728
})
2829
}
2930

31+
if(org.isDeleted){
32+
throw new GraphQLError(`Organization named ${name} was deleted`, {
33+
extensions: {
34+
code: 'AUTHENTICATION_ERROR',
35+
},
36+
})
37+
}
38+
3039
return org
3140
} catch (error: any) {
3241
if (error.message === 'invalid signature') {
@@ -50,3 +59,15 @@ export async function checkLoggedInOrganization(token?: string) {
5059
}
5160
}
5261
}
62+
63+
export function isPartOfOrganization(user: UserInterface, org: IOrganization): OrgUserDataInterface{
64+
const orgUserData = user.organizations.find(data=>data.orgId.toString()===org._id.toString())
65+
if(!orgUserData){
66+
throw new GraphQLError(`User ${user.email} is not part of ${org.name}`,{
67+
extensions: {
68+
code: "FORBIDDEN"
69+
}
70+
})
71+
}
72+
return orgUserData
73+
}

src/helpers/user.helpers.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { GraphQLError } from 'graphql'
2-
import { RoleOfUser, User } from '../models/user'
2+
import { OrgUserDataInterface, RoleOfUser, User, UserInterface } from '../models/user'
33
import { Context } from './../context'
44
import * as jwt from 'jsonwebtoken'
5+
import { IOrganization, Organization } from '../models/organization.model'
56

67
const SECRET: string = process.env.SECRET as string
78

@@ -24,8 +25,9 @@ export const emailExpression =
2425
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
2526

2627
export async function checkUserLoggedIn(
28+
org: InstanceType<typeof Organization>,
2729
context: Context
28-
): Promise<(a?: Array<string>) => Context> {
30+
): Promise<(a?: Array<string>) => { user: UserInterface, orgUserData: OrgUserDataInterface }> {
2931
const { userId, role } = context
3032

3133
if (!userId) {
@@ -45,7 +47,16 @@ export async function checkUserLoggedIn(
4547
})
4648
}
4749

48-
if (user.status?.status !== 'active') {
50+
const orgUserData = user.organizations.find(data=>data.orgId.toString()===org._id.toString())
51+
if(!orgUserData){
52+
throw new GraphQLError(`User ${user.email} is not part of ${org.name}`, {
53+
extensions: {
54+
CODE: 'FORBIDDEN',
55+
},
56+
})
57+
}
58+
59+
if (orgUserData.status?.status !== 'active') {
4960
throw new GraphQLError('User is not active', {
5061
extensions: {
5162
CODE: 'USER_NOT_ACTIVE',
@@ -65,6 +76,6 @@ export async function checkUserLoggedIn(
6576
)
6677
}
6778

68-
return { userId, role }
79+
return { user, orgUserData }
6980
}
7081
}

src/index.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ import ticketSchema from './schema/ticket.shema'
4444
import notificationSchema from './schema/notification.schema'
4545

4646
import statisticsSchema from './schema/invitationStatics.schema'
47-
import StatisticsResolvers from './resolvers/invitationStatics.resolvers'
47+
// import StatisticsResolvers from './resolvers/invitationStatics.resolvers'
4848

4949
import { IResolvers } from '@graphql-tools/utils'
5050
import invitationSchema from './schema/invitation.schema'
51-
import TableViewInvitationResolver from './resolvers/TableViewInvitationResolver'
51+
// import TableViewInvitationResolver from './resolvers/TableViewInvitationResolver'
5252
import eventSchema from './schema/event.schema'
5353
import './utils/cron-jobs/team-jobs'
54+
import userSchema from './schema/user.schema'
5455

5556
const PORT: number = parseInt(process.env.PORT!) || 4000
5657

@@ -66,30 +67,31 @@ export const typeDefs = mergeTypeDefs([
6667
notificationSchema,
6768
statisticsSchema,
6869
eventSchema,
70+
userSchema
6971
])
7072

7173
export const resolvers = mergeResolvers([
7274
userResolvers,
73-
profileResolvers,
74-
programResolvers,
75-
cohortResolvers,
76-
createRatingSystemresolver,
77-
manageStudentResolvers,
78-
ratingResolvers,
79-
replyResolver,
80-
phaseResolver,
81-
teamResolver,
82-
notificationResolver,
83-
eventResolvers,
84-
ticketResolver,
85-
DocumentationResolvers,
86-
attendanceResolver,
87-
Sessionresolvers,
88-
89-
StatisticsResolvers,
90-
91-
invitationResolvers,
92-
TableViewInvitationResolver,
75+
// profileResolvers,
76+
// programResolvers,
77+
// cohortResolvers,
78+
// createRatingSystemresolver,
79+
// manageStudentResolvers,
80+
// ratingResolvers,
81+
// replyResolver,
82+
// phaseResolver,
83+
// teamResolver,
84+
// notificationResolver,
85+
// eventResolvers,
86+
// ticketResolver,
87+
// DocumentationResolvers,
88+
// attendanceResolver,
89+
// Sessionresolvers,
90+
91+
// StatisticsResolvers,
92+
93+
// invitationResolvers,
94+
// TableViewInvitationResolver,
9395
])
9496

9597
async function startApolloServer(

0 commit comments

Comments
 (0)