|
|
@ -12,7 +12,7 @@ import { Server, IncomingMessage, ServerResponse } from 'http' |
|
|
|
import pick from 'lodash/pick' |
|
|
|
|
|
|
|
import { appSchema, errorSchema } from '../../schemas' |
|
|
|
import { getUsers, userIdIsValid, userIsValid } from '../../lib/collections' |
|
|
|
import { getUsers, userIdIsValid, userIsValid, updateItem } from '../../lib/collections' |
|
|
|
import { generateString } from '../../lib/crypto' |
|
|
|
import { containerFor, getItem, normalize, queryItems, createQuerySpec } from '../../lib/database' |
|
|
|
import { unauthorizedError, serverError, badRequestError, notFoundError, forbiddenError } from '../../lib/errors' |
|
|
@ -112,15 +112,17 @@ function appsRoute(server: FastifyInstance<Server, IncomingMessage, ServerRespon |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
|
|
|
|
const { sort = 'created', continuation } = request.query |
|
|
|
const query = `SELECT * FROM Apps a WHERE a.pk = '${APP_PARTITION_KEY}' AND a.active = true ORDER BY a.${sort}` |
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
|
|
|
|
const { resources: apps, requestCharge, continuation: newContinuation } = await container.items.query<App>( |
|
|
|
`SELECT * FROM Apps a WHERE a.pk = '${APP_PARTITION_KEY}' AND a.active = true ORDER BY a.${sort}`, |
|
|
|
{ |
|
|
|
maxItemCount: 40, |
|
|
|
continuation, |
|
|
|
} |
|
|
|
).fetchAll() |
|
|
|
const { |
|
|
|
resources: apps, |
|
|
|
requestCharge, |
|
|
|
continuation: newContinuation, |
|
|
|
} = await container.items.query<App>(query, { |
|
|
|
maxItemCount: 40, |
|
|
|
continuation, |
|
|
|
}).fetchAll() |
|
|
|
|
|
|
|
request.log.trace('Query: %d', requestCharge) |
|
|
|
|
|
|
@ -172,16 +174,16 @@ function selfAppsRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (!request.viewer) return unauthorizedError(reply) |
|
|
|
|
|
|
|
const viewer = containerFor(server.database.client, 'Users').item(request.viewer.id, request.viewer.id).read<User>() |
|
|
|
const viewer = await getItem<User>({ |
|
|
|
container: containerFor(server.database.client, 'Users'), |
|
|
|
id: request.viewer.id, |
|
|
|
}) |
|
|
|
|
|
|
|
const { sort = 'created' } = request.query |
|
|
|
const query = `SELECT * FROM Apps a WHERE a.pk = '${APP_PARTITION_KEY}' AND a.userId = ${request.viewer.id} ORDER BY a.${sort}` |
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
|
|
|
|
const { resources: apps, requestCharge } = await container.items.query<App>( |
|
|
|
`SELECT * FROM Apps a WHERE a.pk = '${APP_PARTITION_KEY}' AND a.userId = ${request.viewer.id} ORDER BY a.${sort}`, |
|
|
|
{} |
|
|
|
).fetchAll() |
|
|
|
|
|
|
|
const { resources: apps, requestCharge } = await container.items.query<App>(query, {}).fetchAll() |
|
|
|
request.log.trace('Query: %d', requestCharge) |
|
|
|
|
|
|
|
return { |
|
|
@ -252,7 +254,9 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp |
|
|
|
server.post<DefaultQuery, DefaultParams, DefaultHeaders, Body>('/v1/app', options, async (request, reply) => { |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (!request.viewer) return unauthorizedError(reply) |
|
|
|
if (!(await userIdIsValid(server.database.client, request.viewer.id))) return unauthorizedError(reply) |
|
|
|
|
|
|
|
const valid = await userIdIsValid(server.database.client, request.viewer.id) |
|
|
|
if (!valid) return forbiddenError(reply) |
|
|
|
|
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
const id = normalize(request.body.name) |
|
|
@ -312,9 +316,7 @@ function createRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp |
|
|
|
if (coverImageUrl) await attachMedia(mediaContainer, coverImageUrl) |
|
|
|
if (iconImageUrl) await attachMedia(mediaContainer, iconImageUrl) |
|
|
|
|
|
|
|
return { |
|
|
|
id, |
|
|
|
} |
|
|
|
return { id } |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
@ -382,7 +384,9 @@ function updateRoute(server: FastifyInstance<Server, IncomingMessage, ServerResp |
|
|
|
server.put<DefaultQuery, Params, DefaultHeaders, Body>('/v1/app/:id', options, async (request, reply) => { |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (!request.viewer) return unauthorizedError(reply) |
|
|
|
if (!(await userIdIsValid(server.database.client, request.viewer.id))) return unauthorizedError(reply) |
|
|
|
|
|
|
|
const valid = await userIdIsValid(server.database.client, request.viewer.id) |
|
|
|
if (!valid) return forbiddenError(reply) |
|
|
|
|
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
const mediaContainer = containerFor(server.database.client, 'Media') |
|
|
@ -790,15 +794,7 @@ function activateRoute(server: FastifyInstance<Server, IncomingMessage, ServerRe |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (request.headers.adminkey !== process.env.ADMIN_KEY) return serverError(reply) |
|
|
|
|
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
const item = container.item(request.params.id, APP_PARTITION_KEY) |
|
|
|
|
|
|
|
const { resource: app } = await item.read<App>() |
|
|
|
await item.replace<App>({ |
|
|
|
...app, |
|
|
|
active: true, |
|
|
|
}) |
|
|
|
|
|
|
|
await updateItem<App>(containerFor(server.database.client, 'Apps').item(request.params.id, APP_PARTITION_KEY), { active: true }) |
|
|
|
reply.code(204) |
|
|
|
}) |
|
|
|
} |
|
|
@ -843,12 +839,7 @@ function setPreinstallRoute(server: FastifyInstance<Server, IncomingMessage, Ser |
|
|
|
if (!server.database) return serverError(reply) |
|
|
|
if (request.headers.adminkey !== process.env.ADMIN_KEY) return serverError(reply) |
|
|
|
|
|
|
|
const container = containerFor(server.database.client, 'Apps') |
|
|
|
const item = container.item(request.params.id, APP_PARTITION_KEY) |
|
|
|
|
|
|
|
const { resource: app } = await item.read<App>() |
|
|
|
await item.replace<App>({ |
|
|
|
...app, |
|
|
|
await updateItem<App>(containerFor(server.database.client, 'Apps').item(request.params.id, APP_PARTITION_KEY), { |
|
|
|
preinstall: true, |
|
|
|
active: true, |
|
|
|
}) |
|
|
|