@ -12,8 +12,9 @@ import merge from 'lodash/merge'
import { Server , IncomingMessage , ServerResponse } from 'http'
import { MIN_ID_LENGTH , MAX_NAME_LENGTH , GROUP_LISTING_PARTITION_KEY } from '../../constants'
import { errorSchema , groupListingSchema } from '../../schemas'
import { errorSchema , groupListingSchema , userSchema } from '../../schemas'
import { unauthorizedError , badRequestError , notFoundError , serverError } from '../../lib/errors'
import { getUsers } from '../../lib/collections'
import { containerFor , createQuerySpec , queryItems , getItem , normalize } from '../../lib/database'
import {
@ -489,12 +490,12 @@ function listRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon
let registrationString = ''
if ( registration ) {
registrationString = ` AND d.registration = ${ registration } `
registrationString = ` AND d.registration = ' ${ registration } ' `
}
const container = containerFor ( server . database . client , 'GroupDirectory' )
const { resources : groups , requestCharge , continuation : newContinuation } = await container . items . query < GroupListing > (
` SELECT * FROM GroupDirectory d WHERE d.pk = ${ GROUP_LISTING_PARTITION_KEY } ${ registrationString } ORDER BY d. ${ sort } ` ,
` SELECT * FROM GroupDirectory d WHERE d.pk = ' ${ GROUP_LISTING_PARTITION_KEY } ' ${ registrationString } ORDER BY d. ${ sort } ` ,
{
maxItemCount : 40 ,
continuation ,
@ -510,6 +511,85 @@ function listRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon
} )
}
function membersRoute ( server : FastifyInstance < Server , IncomingMessage , ServerResponse > ) {
interface Query {
type ? : string
continuation? : string
}
const options : RouteShorthandOptions = {
schema : {
querystring : {
type : 'object' ,
properties : {
type : {
type : 'string' ,
enum : [ 'admin' , 'moderator' , 'member' ] ,
} ,
continuation : { type : 'string' } ,
} ,
} ,
response : {
200 : {
type : 'object' ,
properties : {
members : {
type : 'array' ,
items : userSchema ,
} ,
continuation : { type : 'string' } ,
}
} ,
400 : errorSchema ,
}
} ,
}
server . get < Query , DefaultParams , DefaultHeaders , DefaultBody > ( '/api/group/:id/members' , options , async ( request , reply ) = > {
if ( ! server . database ) return serverError ( reply )
const groupContainer = containerFor ( server . database . client , 'Groups' )
const group = await getItem < Group > ( {
container : groupContainer ,
id : request.params.id ,
logger : request.log
} )
if ( ! group ) return notFoundError ( reply )
const { type , continuation } = request . query
let typeString = ''
if ( type ) {
typeString = ` AND g.membership = ' ${ type } ' `
}
const container = containerFor ( server . database . client , 'Groups' )
const { resources : memberships , requestCharge , continuation : newContinuation } = await container . items . query < GroupMembership > (
` SELECT g.userId, g.membership FROM Groups g WHERE g.pk = ' ${ group . id } ' AND g.t = ' ${ GroupItemType . Membership } ' ${ typeString } ORDER BY g.created DESC ` ,
{
maxItemCount : 100 ,
continuation ,
}
) . fetchAll ( )
request . log . trace ( 'Query: %d' , requestCharge )
const users = await getUsers ( server . database . client , memberships . map ( membership = > membership . userId ) , request . log )
return {
members : users.map ( user = > {
const m = memberships . find ( membership = > membership . userId === user . id )
return {
. . . user ,
membership : m ? m.membership : undefined ,
}
} ) ,
continuation : newContinuation ,
}
} )
}
const plugin : Plugin < Server , IncomingMessage , ServerResponse , PluginOptions > = async server = > {
availabilityRoute ( server )
createRoute ( server )
@ -518,6 +598,7 @@ const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = a
unblockRoute ( server )
activateRoute ( server )
listRoute ( server )
membersRoute ( server )
}
export default plugin