chore(server): accessrequests IoC 11 - processPendingStreamRequestFactory

This commit is contained in:
Kristaps Fabians Geikins
2024-09-11 14:19:16 +03:00
parent 9c2e53b017
commit 415a102dae
4 changed files with 96 additions and 61 deletions
@@ -32,6 +32,13 @@ export type GetPendingAccessRequests = <T extends AccessRequestType>(
resourceId: string
) => Promise<ServerAccessRequestRecord<T, string>[]>
export type GetPendingAccessRequest = <T extends AccessRequestType = AccessRequestType>(
requestId: string,
resourceType?: T
) => Promise<Optional<ServerAccessRequestRecord<T, string>>>
export type DeleteRequestById = (requestId: string) => Promise<boolean>
export type GetUserProjectAccessRequest = (
userId: string,
projectId: string
@@ -3,6 +3,8 @@ import { AccessRequestsEmitter } from '@/modules/accessrequests/events/emitter'
import {
AccessRequestType,
createNewRequestFactory,
deleteRequestByIdFactory,
getPendingAccessRequestFactory,
getPendingAccessRequestsFactory,
getUsersPendingAccessRequestFactory
} from '@/modules/accessrequests/repositories'
@@ -11,8 +13,7 @@ import {
getPendingStreamRequestsFactory,
getUserProjectAccessRequestFactory,
getUserStreamAccessRequestFactory,
processPendingProjectRequest,
processPendingStreamRequest,
processPendingStreamRequestFactory,
requestProjectAccessFactory,
requestStreamAccessFactory
} from '@/modules/accessrequests/services/stream'
@@ -20,7 +21,10 @@ import { Resolvers } from '@/modules/core/graph/generated/graphql'
import { mapStreamRoleToValue } from '@/modules/core/helpers/graphTypes'
import { Roles } from '@/modules/core/helpers/mainConstants'
import { getStream } from '@/modules/core/repositories/streams'
import { validateStreamAccess } from '@/modules/core/services/streams/streamAccessService'
import {
addOrUpdateStreamCollaborator,
validateStreamAccess
} from '@/modules/core/services/streams/streamAccessService'
import { LogicError } from '@/modules/shared/errors'
const getUserProjectAccessRequest = getUserProjectAccessRequestFactory({
@@ -50,6 +54,16 @@ const getPendingStreamRequests = getPendingStreamRequestsFactory({
getPendingProjectRequests
})
const processPendingStreamRequest = processPendingStreamRequestFactory({
getPendingAccessRequest: getPendingAccessRequestFactory({ db }),
validateStreamAccess,
addOrUpdateStreamCollaborator,
deleteRequestById: deleteRequestByIdFactory({ db }),
accessRequestsEmitter: AccessRequestsEmitter.emit
})
const processPendingProjectRequest = processPendingStreamRequest
const resolvers: Resolvers = {
Mutation: {
async streamAccessRequestUse(_parent, args, ctx) {
@@ -1,6 +1,8 @@
import {
AccessRecordInput,
CreateNewRequest,
DeleteRequestById,
GetPendingAccessRequest,
GetPendingAccessRequests,
GetUsersPendingAccessRequest
} from '@/modules/accessrequests/domain/operations'
@@ -85,7 +87,7 @@ export const getPendingAccessRequestsFactory =
}
export const getPendingAccessRequestFactory =
(deps: { db: Knex }) =>
(deps: { db: Knex }): GetPendingAccessRequest =>
async <T extends AccessRequestType = AccessRequestType>(
requestId: string,
resourceType?: T
@@ -102,7 +104,8 @@ export const getPendingAccessRequestFactory =
}
export const deleteRequestByIdFactory =
(deps: { db: Knex }) => async (requestId: string) => {
(deps: { db: Knex }): DeleteRequestById =>
async (requestId: string) => {
if (!requestId) {
throw new InvalidArgumentError('Request ID missing')
}
@@ -6,9 +6,7 @@ import { AccessRequestsEmitter } from '@/modules/accessrequests/events/emitter'
import { StreamAccessRequestGraphQLReturn } from '@/modules/accessrequests/helpers/graphTypes'
import {
AccessRequestType,
deleteRequestByIdFactory,
generateId,
getPendingAccessRequestFactory,
ServerAccessRequestRecord,
StreamAccessRequestRecord
} from '@/modules/accessrequests/repositories'
@@ -21,10 +19,15 @@ import {
validateStreamAccess
} from '@/modules/core/services/streams/streamAccessService'
import { ensureError } from '@/modules/shared/helpers/errorHelper'
import { MaybeNullOrUndefined, Nullable } from '@/modules/shared/helpers/typeHelper'
import { db } from '@/db/knex'
import {
MaybeNullOrUndefined,
Nullable,
Optional
} from '@/modules/shared/helpers/typeHelper'
import {
CreateNewRequest,
DeleteRequestById,
GetPendingAccessRequest,
GetPendingAccessRequests,
GetPendingProjectRequests,
GetUserProjectAccessRequest,
@@ -159,59 +162,67 @@ export const getPendingStreamRequestsFactory =
/**
* Accept or decline a pending access request
*/
export async function processPendingStreamRequest(
userId: string,
requestId: string,
accept: boolean,
role: StreamRoles = Roles.Stream.Contributor,
resourceAccessRules: MaybeNullOrUndefined<TokenResourceIdentifier[]>
) {
const req = await getPendingAccessRequestFactory({ db })(
requestId,
AccessRequestType.Stream
)
if (!req) {
throw new AccessRequestProcessingError('No request with this ID exists')
}
try {
await validateStreamAccess(
userId,
req.resourceId,
Roles.Stream.Owner,
resourceAccessRules
export const processPendingStreamRequestFactory =
(deps: {
getPendingAccessRequest: GetPendingAccessRequest
validateStreamAccess: typeof validateStreamAccess
addOrUpdateStreamCollaborator: typeof addOrUpdateStreamCollaborator
deleteRequestById: DeleteRequestById
accessRequestsEmitter: (typeof AccessRequestsEmitter)['emit']
}) =>
async (
userId: string,
requestId: string,
accept: boolean,
role: StreamRoles = Roles.Stream.Contributor,
resourceAccessRules: MaybeNullOrUndefined<TokenResourceIdentifier[]>
) => {
const req: Optional<StreamAccessRequestRecord> = await deps.getPendingAccessRequest(
requestId,
AccessRequestType.Stream
)
} catch (e: unknown) {
const err = ensureError(e, 'Stream access validation failed')
if (err instanceof StreamInvalidAccessError) {
throw new AccessRequestProcessingError(
'You must own the stream to process access requests',
{ cause: err }
)
} else {
throw err
if (!req) {
throw new AccessRequestProcessingError('No request with this ID exists')
}
try {
await deps.validateStreamAccess(
userId,
req.resourceId,
Roles.Stream.Owner,
resourceAccessRules
)
} catch (e: unknown) {
const err = ensureError(e, 'Stream access validation failed')
if (err instanceof StreamInvalidAccessError) {
throw new AccessRequestProcessingError(
'You must own the stream to process access requests',
{ cause: err }
)
} else {
throw err
}
}
if (accept) {
await deps.addOrUpdateStreamCollaborator(
req.resourceId,
req.requesterId,
role,
userId,
resourceAccessRules
)
}
await deps.deleteRequestById(req.id)
await deps.accessRequestsEmitter(AccessRequestsEmitter.events.Finalized, {
request: req,
approved: accept ? { role } : undefined,
finalizedBy: userId
})
return req
}
if (accept) {
await addOrUpdateStreamCollaborator(
req.resourceId,
req.requesterId,
role,
userId,
resourceAccessRules
)
}
await deleteRequestByIdFactory({ db })(req.id)
await AccessRequestsEmitter.emit(AccessRequestsEmitter.events.Finalized, {
request: req,
approved: accept ? { role } : undefined,
finalizedBy: userId
})
return req
}
export const processPendingProjectRequest = processPendingStreamRequest
export const processPendingProjectRequest = processPendingStreamRequestFactory