|
|
@ -721,6 +721,86 @@ function createInvitationRoute(server: FastifyInstance<Server, IncomingMessage, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function invitationsRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) { |
|
|
|
interface Query { |
|
|
|
continuation?: string |
|
|
|
} |
|
|
|
|
|
|
|
const options: RouteShorthandOptions = { |
|
|
|
schema: { |
|
|
|
querystring: { |
|
|
|
type: 'object', |
|
|
|
properties: { |
|
|
|
continuation: { type: 'string' }, |
|
|
|
}, |
|
|
|
}, |
|
|
|
response: { |
|
|
|
200: { |
|
|
|
type: 'object', |
|
|
|
properties: { |
|
|
|
invitations: { |
|
|
|
type: 'array', |
|
|
|
items: { |
|
|
|
type: 'object', |
|
|
|
properties: { |
|
|
|
id: { type: 'string' }, |
|
|
|
user: userSchema, |
|
|
|
uses: { type: 'number' }, |
|
|
|
expiration: { type: 'number' }, |
|
|
|
limit: { type: 'number' }, |
|
|
|
created: { type: 'number' }, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
continuation: { type: 'string' }, |
|
|
|
}, |
|
|
|
}, |
|
|
|
400: errorSchema, |
|
|
|
}, |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
server.get<Query, DefaultParams, DefaultHeaders, DefaultBody>('/api/group/:id/invitations', options, async (request, reply) => { |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (!request.viewer) return unauthorizedError(reply) |
|
|
|
|
|
|
|
const membership = await getUserMembership(server.database.client, request.viewer.id, request.log) |
|
|
|
if (!membership || membership.membership !== GroupMembershipType.Admin) return unauthorizedError(reply) |
|
|
|
|
|
|
|
const container = containerFor(server.database.client, 'Groups') |
|
|
|
|
|
|
|
const group = await getItem<Group>({ container, id: request.params.id }) |
|
|
|
if (!group) return notFoundError(reply) |
|
|
|
|
|
|
|
const { continuation } = request.query |
|
|
|
|
|
|
|
const { resources: invitations, requestCharge, continuation: newContinuation } = await container.items.query<GroupLog>( |
|
|
|
`SELECT * FROM Groups g WHERE
|
|
|
|
g.pk = '${group.id}' AND |
|
|
|
g.t = '${GroupItemType.Invitation}' AND |
|
|
|
g.expiration < GETCURRENTTIMESTAMP() AND |
|
|
|
g.active = true ORDER BY g.created DESC`,
|
|
|
|
{ |
|
|
|
maxItemCount: 80, |
|
|
|
continuation, |
|
|
|
} |
|
|
|
).fetchAll() |
|
|
|
|
|
|
|
request.log.trace('Query: %d', requestCharge) |
|
|
|
|
|
|
|
const users = await getUsers(server.database.client, invitations.map(invitation => invitation.userId), request.log) |
|
|
|
|
|
|
|
return { |
|
|
|
invitations: invitations.map(invitation => ({ |
|
|
|
...invitation, |
|
|
|
user: users.find(user => user.id === invitation.userId), |
|
|
|
userId: undefined, |
|
|
|
})), |
|
|
|
continuation: newContinuation, |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function logsRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) { |
|
|
|
interface Query { |
|
|
|
continuation?: string |
|
|
@ -743,6 +823,7 @@ function logsRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon |
|
|
|
items: { |
|
|
|
type: 'object', |
|
|
|
properties: { |
|
|
|
id: { type: 'string' }, |
|
|
|
user: userSchema, |
|
|
|
content: { type: 'string' }, |
|
|
|
created: { type: 'number' }, |
|
|
@ -779,6 +860,8 @@ function logsRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon |
|
|
|
} |
|
|
|
).fetchAll() |
|
|
|
|
|
|
|
request.log.debug('Logs: %o', logs) |
|
|
|
|
|
|
|
request.log.trace('Query: %d', requestCharge) |
|
|
|
|
|
|
|
const users = await getUsers(server.database.client, logs.map(log => log.userId), request.log) |
|
|
@ -805,6 +888,7 @@ const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = a |
|
|
|
listRoute(server) |
|
|
|
membersRoute(server) |
|
|
|
createInvitationRoute(server) |
|
|
|
invitationsRoute(server) |
|
|
|
logsRoute(server) |
|
|
|
} |
|
|
|
|
|
|
|