|
|
@ -8,13 +8,29 @@ import { |
|
|
|
DefaultHeaders, |
|
|
|
} from 'fastify' |
|
|
|
|
|
|
|
import merge from 'lodash/merge' |
|
|
|
import { Server, IncomingMessage, ServerResponse } from 'http' |
|
|
|
|
|
|
|
import { MIN_ID_LENGTH, MAX_NAME_LENGTH } from '../../constants' |
|
|
|
import { MIN_ID_LENGTH, MAX_NAME_LENGTH, GROUP_LISTING_PARTITION_KEY } from '../../constants' |
|
|
|
import { errorSchema, groupListingSchema } from '../../schemas' |
|
|
|
import { unauthorizedError, badRequestError, notFoundError, serverError } from '../../lib/errors' |
|
|
|
import { containerFor, createQuerySpec, queryItems, getItem, normalize } from '../../lib/database' |
|
|
|
import { User, Group, GroupListing, GroupMembership, UserBlock, GroupBlock, GroupRegistrationType } from '../../types/collections' |
|
|
|
|
|
|
|
import { |
|
|
|
User, |
|
|
|
Group, |
|
|
|
GroupListing, |
|
|
|
GroupMembership, |
|
|
|
UserBlock, |
|
|
|
GroupBlock, |
|
|
|
GroupRegistrationType, |
|
|
|
GroupStatus, |
|
|
|
GroupMembershipType, |
|
|
|
GroupItemType, |
|
|
|
BlockType, |
|
|
|
UserItemType |
|
|
|
} from '../../types/collections' |
|
|
|
|
|
|
|
import { PluginOptions } from '../../types' |
|
|
|
|
|
|
|
function availabilityRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) { |
|
|
@ -127,12 +143,12 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp |
|
|
|
const group: Group = { |
|
|
|
id: id, |
|
|
|
pk: id, |
|
|
|
t: 'group', |
|
|
|
t: GroupItemType.Group, |
|
|
|
userId: request.viewer.id, |
|
|
|
name, |
|
|
|
about, |
|
|
|
registration, |
|
|
|
status: 'pending', |
|
|
|
status: GroupStatus.Pending, |
|
|
|
active: true, |
|
|
|
created: Date.now(), |
|
|
|
} |
|
|
@ -140,10 +156,10 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp |
|
|
|
const membership: GroupMembership = { |
|
|
|
id: request.viewer.id, |
|
|
|
pk: id, |
|
|
|
t: 'membership', |
|
|
|
t: GroupItemType.Membership, |
|
|
|
userId: request.viewer.id, |
|
|
|
pending: false, |
|
|
|
membership: 'admin', |
|
|
|
membership: GroupMembershipType.Admin, |
|
|
|
created: Date.now(), |
|
|
|
} |
|
|
|
|
|
|
@ -188,14 +204,54 @@ function getRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespons |
|
|
|
server.get<DefaultQuery, Params, DefaultHeaders, DefaultBody>('/api/group/:id', options, async (request, reply) => { |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
|
|
|
|
const groupContainer = containerFor(server.database.client, 'Groups') |
|
|
|
|
|
|
|
const listing = await getItem<GroupListing>({ |
|
|
|
container: containerFor(server.database.client, 'GroupDirectory'), |
|
|
|
id: request.params.id, |
|
|
|
partitionKey: 'pk', |
|
|
|
logger: request.log, |
|
|
|
}) |
|
|
|
|
|
|
|
if (!listing) return notFoundError(reply) |
|
|
|
return listing |
|
|
|
const group = await getItem<Group>({ |
|
|
|
container: groupContainer, |
|
|
|
id: request.params.id, |
|
|
|
logger: request.log, |
|
|
|
}) |
|
|
|
|
|
|
|
const combine = async (group: Group, listing: GroupListing) => { |
|
|
|
if (request.viewer) { |
|
|
|
const memberships = await queryItems<GroupMembership>({ |
|
|
|
container: groupContainer, |
|
|
|
query: createQuerySpec( |
|
|
|
`
|
|
|
|
SELECT * FROM Groups g WHERE |
|
|
|
g.pk = @pk AND |
|
|
|
g.t = @type AND |
|
|
|
g.userId = @userId AND |
|
|
|
g.pending = false |
|
|
|
`,
|
|
|
|
{ |
|
|
|
pk: group.id, |
|
|
|
type: GroupItemType.Membership, |
|
|
|
userId: request.viewer.id, |
|
|
|
} |
|
|
|
), |
|
|
|
logger: request.log, |
|
|
|
}) |
|
|
|
|
|
|
|
if (memberships.length > 0) { |
|
|
|
return merge(group, listing, { |
|
|
|
membership: memberships[0].membership, |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return merge(group, listing) |
|
|
|
} |
|
|
|
|
|
|
|
if (!group || !listing) return notFoundError(reply) |
|
|
|
return combine(group, listing) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
@ -240,15 +296,15 @@ function blockRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespo |
|
|
|
await containerFor(server.database.client, 'Users').items.create<UserBlock>({ |
|
|
|
blockedId: group.id, |
|
|
|
pk: request.viewer.id, |
|
|
|
t: 'block', |
|
|
|
blockType: 'group', |
|
|
|
t: UserItemType.Block, |
|
|
|
blockType: BlockType.Group, |
|
|
|
description: request.body.description, |
|
|
|
created: Date.now(), |
|
|
|
}) |
|
|
|
|
|
|
|
await groupContainer.items.create<GroupBlock>({ |
|
|
|
pk: group.id, |
|
|
|
t: 'block', |
|
|
|
t: GroupItemType.Block, |
|
|
|
blockedId: group.id, |
|
|
|
userId: request.viewer.id, |
|
|
|
created: Date.now(), |
|
|
@ -288,9 +344,10 @@ function unblockRoute(server: FastifyInstance<Server, IncomingMessage, ServerRes |
|
|
|
}) |
|
|
|
if (!group) return notFoundError(reply) |
|
|
|
|
|
|
|
const userBlockQuery = createQuerySpec(`SELECT u.id FROM Users u WHERE u.pk = @pk AND u.blockedId = @blocked AND u.type = 'block'`, { |
|
|
|
const userBlockQuery = createQuerySpec(`SELECT u.id FROM Users u WHERE u.pk = @pk AND u.blockedId = @blocked AND u.t = @type`, { |
|
|
|
pk: request.viewer.id, |
|
|
|
blocked: group.id, |
|
|
|
type: UserItemType.Block, |
|
|
|
}) |
|
|
|
|
|
|
|
const userBlocks = await queryItems<UserBlock>({ |
|
|
@ -303,11 +360,12 @@ function unblockRoute(server: FastifyInstance<Server, IncomingMessage, ServerRes |
|
|
|
} |
|
|
|
|
|
|
|
const groupBlockQuery = createQuerySpec( |
|
|
|
`SELECT g.id FROM Groups g WHERE g.pk = @pk AND u.blockedId = @blocked AND u.userId = @viewer AND u.type = 'block'`, |
|
|
|
`SELECT g.id FROM Groups g WHERE g.pk = @pk AND u.blockedId = @blocked AND u.userId = @viewer AND u.t = @type`, |
|
|
|
{ |
|
|
|
pk: group.id, |
|
|
|
blocked: group.id, |
|
|
|
viewer: request.viewer.id, |
|
|
|
type: GroupItemType.Block, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
@ -359,11 +417,11 @@ function activateRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe |
|
|
|
await groupItem.replace<Group>({ |
|
|
|
...group, |
|
|
|
active: true, |
|
|
|
status: 'paid', |
|
|
|
status: GroupStatus.Paid, |
|
|
|
}) |
|
|
|
|
|
|
|
const directoryContainer = containerFor(server.database.client, 'GroupDirectory') |
|
|
|
const listingItem = directoryContainer.item(request.params.id, 'pk') |
|
|
|
const listingItem = directoryContainer.item(request.params.id, GROUP_LISTING_PARTITION_KEY) |
|
|
|
const { resource: listing, requestCharge: listingRequestCharge } = await listingItem.read<GroupListing>() |
|
|
|
request.log.trace('Get: %d', listingRequestCharge) |
|
|
|
|
|
|
@ -371,7 +429,7 @@ function activateRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe |
|
|
|
await directoryContainer.items.create<GroupListing>({ |
|
|
|
id: group.id, |
|
|
|
name: group.name, |
|
|
|
pk: 'pk', |
|
|
|
pk: GROUP_LISTING_PARTITION_KEY, |
|
|
|
registration: group.registration, |
|
|
|
members: 1, |
|
|
|
posts: 0, |
|
|
@ -436,7 +494,7 @@ function listRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon |
|
|
|
|
|
|
|
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 = 'pk' ${registrationString} ORDER BY d.${sort}`, |
|
|
|
`SELECT * FROM GroupDirectory d WHERE d.pk = ${GROUP_LISTING_PARTITION_KEY} ${registrationString} ORDER BY d.${sort}`, |
|
|
|
{ |
|
|
|
maxItemCount: 40, |
|
|
|
continuation, |
|
|
|