Skip to content

Commit

Permalink
feat: manage access
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinand11 committed Dec 3, 2023
1 parent b9b56a3 commit f173019
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 2 deletions.
19 changes: 19 additions & 0 deletions services/api/src/application/controllers/study/quizzes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,23 @@ export class QuizController {
if (updatedQuiz) return updatedQuiz
throw new NotAuthorizedError()
}

static async addMembers (req: Request) {
const { userIds, grant } = validate({
userIds: Schema.array(Schema.string().min(1)).min(1),
grant: Schema.boolean()
}, req.body)

if (grant) {
const users = await UsersUseCases.get({
where: [{ field: 'id', value: userIds, condition: Conditions.in }]
})
const activeUsers = users.results.filter((u) => !u.isDeleted())
if (userIds.length !== activeUsers.length) throw new BadRequestError('some users not found')
}

const updatedQuiz = await QuizzesUseCases.addMembers({ id: req.params.id, ownerId: req.authUser!.id, userIds, grant })
if (updatedQuiz) return updatedQuiz
throw new NotAuthorizedError()
}
}
12 changes: 12 additions & 0 deletions services/api/src/application/routes/study/quizzes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,17 @@ export const quizzesRoutes = groupRoutes('/quizzes', [
}
})
]
}, {
path: '/:id/access/members/manage',
method: 'post',
controllers: [
isAuthenticated,
makeController(async (req) => {
return {
status: StatusCodes.Ok,
result: await QuizController.addMembers(req)
}
})
]
}
])
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export enum NotificationType {
NewQuizAccessRequest = 'NewQuizAccessRequest',
QuizAccessRequestGranted = 'QuizAccessRequestGranted',
QuizAccessRequestRejected = 'QuizAccessRequestRejected',
QuizAccessMemberGranted = 'QuizAccessMemberGranted',
QuizAccessMemberRebuked = 'QuizAccessMemberRebuked',
}

export type NotificationData =
Expand All @@ -35,4 +37,6 @@ export type NotificationData =
| { type: NotificationType.SubscriptionFailed, planId: string }
| { type: NotificationType.NewQuizAccessRequest, userIds: string[] }
| { type: NotificationType.QuizAccessRequestGranted, quizId: string }
| { type: NotificationType.QuizAccessRequestRejected, quizId: string }
| { type: NotificationType.QuizAccessRequestRejected, quizId: string }
| { type: NotificationType.QuizAccessMemberGranted, quizId: string }
| { type: NotificationType.QuizAccessMemberRebuked, quizId: string }
17 changes: 17 additions & 0 deletions services/api/src/modules/study/data/repositories/quizzes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,21 @@ export class QuizRepository implements IQuizRepository {
})
return !!quiz
}

async addMembers(id: string, ownerId: string, userIds: string[], grant: boolean) {
const quiz = await Quiz.findByIdAndUpdate({
_id: id, 'user.id': ownerId,
}, {
...(grant ? {
$addToSet: { 'access.members': { '$each': userIds } },
$pull: { 'access.requests': { '$in': userIds } },
} : {
$pull: {
'access.members': { '$in': userIds },
'access.requests': { '$in': userIds },
},
})
})
return !!quiz
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export interface IQuizRepository {
updateRatings (id: string, ratings: number, add: boolean): Promise<boolean>
requestAccess (id: string, userId: string, add: boolean): Promise<boolean>
grantAccess (id: string, ownerId: string, userId: string, grant: boolean): Promise<boolean>
addMembers (id: string, ownerId: string, userIds: string[], grant: boolean): Promise<boolean>
}
4 changes: 4 additions & 0 deletions services/api/src/modules/study/domain/useCases/quizzes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ export class QuizzesUseCase {
async grantAccess (data: { id: string, ownerId: string, userId: string, grant: boolean }) {
return await this.repository.grantAccess(data.id, data.ownerId, data.userId, data.grant)
}

async addMembers (data: { id: string, ownerId: string, userIds: string[], grant: boolean }) {
return await this.repository.addMembers(data.id, data.ownerId, data.userIds, data.grant)
}
}
17 changes: 16 additions & 1 deletion services/api/src/modules/study/utils/changes/quizzes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ export const QuizDbChangeCallbacks: DbChangeCallbacks<QuizFromModel, QuizEntity>
property: UserMeta.publishedQuizzes
})

if (changes.access?.requests) {
if (changes.access) {
const newRequests = after.access.requests.filter((r) => !before.access.requests.includes(r))
const oldRequests = before.access.requests.filter((r) => !after.access.requests.includes(r))
const accepted = oldRequests.filter((r) => after.access.members.includes(r))
const rejected = oldRequests.filter((r) => !after.access.members.includes(r))
const added = after.access.members.filter((m) => !before.access.members.includes(m))
.filter((m) => !accepted.includes(m))
const removed = before.access.members.filter((m) => !after.access.members.includes(m))
if (newRequests.length) await sendNotification([after.user.id], {
title: 'New Quiz Edit Request',
body: `Someone just requested access to edit your quiz: ${after.title}`,
Expand All @@ -66,6 +69,18 @@ export const QuizDbChangeCallbacks: DbChangeCallbacks<QuizFromModel, QuizEntity>
sendEmail: true,
data: { type: NotificationType.QuizAccessRequestRejected, quizId: after.id }
})
if (added.length) await sendNotification(added, {
title: 'Quiz Edit Request Granted',
body: `You have been granted access to edit ${after.title}`,
sendEmail: true,
data: { type: NotificationType.QuizAccessMemberGranted, quizId: after.id }
})
if (removed.length) await sendNotification(removed, {
title: 'Quiz Edit Request Rebuked',
body: `Your access to edit ${after.title} has been rebuked`,
sendEmail: true,
data: { type: NotificationType.QuizAccessMemberRebuked, quizId: after.id }
})
}
},
deleted: async ({ before }) => {
Expand Down

0 comments on commit f173019

Please sign in to comment.