@appsemble/node-utils
Version:
NodeJS utilities used by Appsemble internally.
66 lines • 3.1 kB
JavaScript
import { defaultLocale, remap } from '@appsemble/lang-sdk';
import { getRemapperContext, getResourceDefinition, } from '@appsemble/node-utils';
import { generateResourceQuery, getGroupIdWhere } from '../../../../utils/resources.js';
export function createQueryAppResourcesController(options) {
return async (ctx) => {
const { pathParams: { appId, resourceType }, queryParams: { $own, $select, $skip, $top, selectedGroupId, view }, user: authSubject, } = ctx;
const { checkAppPermissions, getAllowedGroups, getApp, getAppResources } = options;
const app = await getApp({
context: ctx,
query: { attributes: ['definition', 'demoMode', 'id', 'template'], where: { id: appId } },
});
const resourceDefinition = getResourceDefinition(app.definition, resourceType, ctx, view);
const { order, where } = generateResourceQuery(ctx, options, resourceDefinition);
const permissions = [
$own
? `$resource:${resourceType}:own:query`
: view
? `$resource:${resourceType}:query:${view}`
: `$resource:${resourceType}:query`,
];
// Across multiple selected groups the permission acts as a filter: only the
// groups the subject may query are returned. When no selected group is
// queryable, the strict permission check throws its usual 403.
const allowedGroups = await getAllowedGroups({
context: ctx,
permissions,
app,
groupId: selectedGroupId,
});
if (!allowedGroups.length) {
await checkAppPermissions({ context: ctx, permissions, app, groupId: selectedGroupId });
}
const isSameOrigin = ctx?.headers?.origin === ctx?.headers?.host;
const findOptions = {
limit: $top,
offset: $skip,
attributes: $select?.split(',').map((s) => s.trim()),
where: {
and: [
where,
{
type: resourceType,
GroupId: getGroupIdWhere(allowedGroups.length ? allowedGroups : selectedGroupId),
expires: { or: [{ gt: new Date() }, null] },
...(app.demoMode && !isSameOrigin ? { seed: false, ephemeral: true } : {}),
...($own ? { AuthorId: authSubject?.id } : {}),
},
],
},
order,
};
const resources = await getAppResources({
app,
findOptions,
type: resourceType,
context: ctx,
});
if (view) {
const context = await getRemapperContext(app, app.definition.defaultLanguage || defaultLocale, options, ctx);
ctx.body = resources.map((resource) => remap(resourceDefinition.views?.[view].remap ?? null, resource, context));
return;
}
ctx.body = resources;
};
}
//# sourceMappingURL=createQueryAppResourcesController.js.map