@drodil/backstage-plugin-qeta-backend 3.54.0 → 3.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/database/DatabaseQetaStore.cjs.js +1 -0
- package/dist/database/DatabaseQetaStore.cjs.js.map +1 -1
- package/dist/database/stores/CollectionsStore.cjs.js +262 -23
- package/dist/database/stores/CollectionsStore.cjs.js.map +1 -1
- package/dist/database/stores/PostsStore.cjs.js +6 -0
- package/dist/database/stores/PostsStore.cjs.js.map +1 -1
- package/dist/service/routes/collections.cjs.js +6 -0
- package/dist/service/routes/collections.cjs.js.map +1 -1
- package/dist/service/routes/helpers.cjs.js +35 -4
- package/dist/service/routes/helpers.cjs.js.map +1 -1
- package/dist/service/routes/posts.cjs.js +23 -13
- package/dist/service/routes/posts.cjs.js.map +1 -1
- package/dist/service/routes/routeUtil.cjs.js +33 -0
- package/dist/service/routes/routeUtil.cjs.js.map +1 -1
- package/dist/service/routes/statistics.cjs.js +109 -71
- package/dist/service/routes/statistics.cjs.js.map +1 -1
- package/dist/service/routes/suggestions.cjs.js +34 -20
- package/dist/service/routes/suggestions.cjs.js.map +1 -1
- package/dist/service/types.cjs.js +4 -1
- package/dist/service/types.cjs.js.map +1 -1
- package/dist/service/util.cjs.js +74 -18
- package/dist/service/util.cjs.js.map +1 -1
- package/migrations/20260109_automatic_collections.js +59 -0
- package/migrations/20260110_optimize_indexes.js +43 -0
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.cjs.js","sources":["../../../src/service/routes/collections.ts"],"sourcesContent":["import { getCreated, mapAdditionalFields } from '../util';\nimport Ajv from 'ajv';\nimport { Router } from 'express';\nimport {\n CollectionsQuery,\n qetaCreateCollectionPermission,\n qetaDeleteCollectionPermission,\n qetaEditCollectionPermission,\n qetaReadCollectionPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport addFormats from 'ajv-formats';\nimport {\n CollectionPostSchema,\n CollectionRankPostSchema,\n CollectionSchema,\n CollectionsQuerySchema,\n DeleteMetadataSchema,\n RouteOptions,\n} from '../types';\nimport { entityToJsonObject, validateDateRange, wrapAsync } from './util';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const collectionsRoutes = (router: Router, options: RouteOptions) => {\n const { database, events, notificationMgr, auditor, permissionMgr } = options;\n // GET /collections\n router.get(`/collections`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(CollectionsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.query.fromDate as string,\n request.query.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const conditions = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const postFilters = conditions[0];\n const filters = conditions[1];\n const tagFilters = conditions[2];\n\n const opts = request.query as CollectionsQuery;\n // Act\n const collections = await database.getCollections(username, opts, {\n filters,\n postFilters,\n tagFilters,\n });\n\n await mapAdditionalFields(request, collections.collections, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n\n response.json(collections);\n });\n\n router.post(`/collections/query`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(CollectionsQuerySchema);\n if (!validateQuery(request.body)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.body.fromDate as string,\n request.body.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const opts = request.body;\n\n // Act\n const collections = await database.getCollections(username, opts, {\n filters,\n postFilters,\n tagFilters,\n });\n\n await mapAdditionalFields(request, collections.collections, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n\n response.json(collections);\n });\n\n // POST /collections\n router.post(`/collections`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateCollectionPermission }],\n { throwOnDeny: true },\n );\n\n const username = await permissionMgr.getUsername(request);\n const created = await getCreated(request, options);\n\n // Act\n const collection = await database.createCollection({\n user_ref: username,\n title: request.body.title,\n description: request.body.description,\n created,\n images: request.body.images,\n headerImage: request.body.headerImage,\n opts: { includePosts: false },\n });\n\n if (!collection) {\n response\n .status(400)\n .send({ errors: 'Failed to create collection', type: 'body' });\n return;\n }\n\n wrapAsync(async () => {\n const followingUsers = await Promise.all([\n database.getFollowingUsers(username),\n ]);\n await notificationMgr.onNewCollection(\n username,\n collection,\n followingUsers.flat(),\n );\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'new_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'create-collection',\n severityLevel: 'medium',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n // Response\n response.status(201).json(collection);\n });\n\n // POST /collections/:id\n router.post(`/collections/:id`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n const originalCollection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!originalCollection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n {\n permission: qetaEditCollectionPermission,\n resource: originalCollection,\n },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n const collection = await database.updateCollection({\n id: collectionId,\n user_ref: username,\n title: request.body.title,\n description: request.body.description,\n images: request.body.images,\n headerImage: request.body.headerImage,\n opts: { postFilters, tagFilters, filters },\n });\n\n if (!collection) {\n response.sendStatus(401);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'update-collection',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalCollection),\n to: entityToJsonObject(collection),\n },\n });\n\n // Response\n response.json(collection);\n });\n\n // DELETE /collections/:id\n router.delete('/collections/:id', async (request, response) => {\n // Validation\n const collectionId = Number.parseInt(request.params.id, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(collectionId) || !validateRequestBody(request.body)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n const username = await permissionMgr.getUsername(request);\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n // Act\n const deleted = await database.deleteCollection(collectionId);\n\n if (deleted && events) {\n events.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n reason: request.body.reason,\n },\n metadata: { action: 'delete_collection' },\n });\n }\n\n if (deleted) {\n notificationMgr.onCollectionDelete(\n username,\n collection,\n request.body.reason,\n );\n auditor?.createEvent({\n eventId: 'delete-collection',\n severityLevel: 'medium',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n reason: request.body.reason,\n },\n });\n }\n\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/collections/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const collections = await database.getUserCollections(username, {\n filters,\n postFilters,\n tagFilters,\n });\n response.json(collections);\n });\n\n router.put('/collections/follow/:id', async (request, response) => {\n const { id } = request.params;\n const collectionId = Number.parseInt(id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n }\n\n const username = await permissionMgr.getUsername(request, false);\n const collection = await database.getCollection(username, collectionId);\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n await database.followCollection(username, collectionId);\n\n auditor?.createEvent({\n eventId: 'follow-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n response.status(204).send();\n });\n\n router.delete('/collections/follow/:id', async (request, response) => {\n const { id } = request.params;\n const collectionId = Number.parseInt(id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n }\n\n const username = await permissionMgr.getUsername(request, false);\n const collection = await database.getCollection(username, collectionId);\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n await database.unfollowCollection(username, collectionId);\n\n auditor?.createEvent({\n eventId: 'unfollow-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n response.status(204).send();\n });\n\n // GET /collections/:id\n router.get(`/collections/:id`, async (request, response) => {\n // Validation\n // Act\n const username = await permissionMgr.getUsername(request);\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n { postFilters, tagFilters },\n );\n\n if (collection === null) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'read-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n // Response\n response.json(collection);\n });\n\n // POST /collections/:id\n router.post(`/collections/:id/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n let collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n const post = await database.getPost(username, request.body.postId, false);\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection! },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n collection = await database.addPostToCollection(\n username,\n collectionId,\n request.body.postId,\n { postFilters, tagFilters },\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n wrapAsync(async () => {\n if (!collection) {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForCollection(collectionId),\n database.getFollowingUsers(username),\n ]);\n await notificationMgr.onNewPostToCollection(\n username,\n collection,\n followingUsers.flat(),\n );\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'add-to-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n },\n });\n\n // Response\n response.status(200);\n response.json(collection);\n });\n\n // DELETE /collections/:id/posts\n router.delete(`/collections/:id/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n let collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n const post = await database.getPost(username, request.body.postId, false);\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection! },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n collection = await database.removePostFromCollection(\n username,\n collectionId,\n request.body.postId,\n { postFilters, tagFilters },\n );\n\n if (!collection) {\n response\n .status(404)\n .send({ errors: 'Collection not found', type: 'body' });\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'delete-from-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n },\n });\n\n // Response\n response.status(200);\n response.json(collection);\n });\n\n router.post('/collections/:id/rank/', async (request, response) => {\n const validateRequestBody = ajv.compile(CollectionRankPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n const post = await database.getPost(username, request.body.postId, false);\n\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const currentRank = await database.getPostRank(\n collection.id,\n request.body.postId,\n );\n if (!currentRank) {\n response.status(404).send();\n return;\n }\n\n if (request.body.rank === 'up') {\n const higherRankPostId = await database.getNextRankedPostId(\n collection.id,\n request.body.postId,\n );\n if (higherRankPostId) {\n await database.updatePostRank(\n collection.id,\n higherRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n higherRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'down') {\n const lowerRankPostId = await database.getPreviousRankedPostId(\n collection.id,\n request.body.postId,\n );\n if (lowerRankPostId) {\n await database.updatePostRank(\n collection.id,\n lowerRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n lowerRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'top') {\n const topRankPostId = await database.getTopRankedPostId(collectionId);\n if (topRankPostId) {\n await database.updatePostRank(\n collection.id,\n topRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n topRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'bottom') {\n const bottomRankPostId = await database.getBottomRankedPostId(\n collection.id,\n );\n if (bottomRankPostId) {\n await database.updatePostRank(\n collection.id,\n bottomRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n bottomRankPostId.rank,\n );\n }\n }\n\n auditor?.createEvent({\n eventId: 'rank-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n rank: request.body.rank,\n },\n });\n\n response.sendStatus(200);\n });\n};\n"],"names":["Ajv","addFormats","CollectionsQuerySchema","validateDateRange","qetaReadPostPermission","qetaReadCollectionPermission","qetaReadTagPermission","mapAdditionalFields","CollectionSchema","qetaCreateCollectionPermission","getCreated","wrapAsync","entityToJsonObject","qetaEditCollectionPermission","DeleteMetadataSchema","qetaDeleteCollectionPermission","CollectionPostSchema","CollectionRankPostSchema"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collections.cjs.js","sources":["../../../src/service/routes/collections.ts"],"sourcesContent":["import { getCreated, mapAdditionalFields } from '../util';\nimport Ajv from 'ajv';\nimport { Router } from 'express';\nimport {\n CollectionsQuery,\n qetaCreateCollectionPermission,\n qetaDeleteCollectionPermission,\n qetaEditCollectionPermission,\n qetaReadCollectionPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport addFormats from 'ajv-formats';\nimport {\n CollectionPostSchema,\n CollectionRankPostSchema,\n CollectionSchema,\n CollectionsQuerySchema,\n DeleteMetadataSchema,\n RouteOptions,\n} from '../types';\nimport { entityToJsonObject, validateDateRange, wrapAsync } from './util';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const collectionsRoutes = (router: Router, options: RouteOptions) => {\n const { database, events, notificationMgr, auditor, permissionMgr } = options;\n // GET /collections\n router.get(`/collections`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(CollectionsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.query.fromDate as string,\n request.query.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const conditions = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const postFilters = conditions[0];\n const filters = conditions[1];\n const tagFilters = conditions[2];\n\n const opts = request.query as CollectionsQuery;\n // Act\n const collections = await database.getCollections(username, opts, {\n filters,\n postFilters,\n tagFilters,\n });\n\n await mapAdditionalFields(request, collections.collections, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n\n response.json(collections);\n });\n\n router.post(`/collections/query`, async (request, response) => {\n // Validation\n const username = await permissionMgr.getUsername(request, true);\n const validateQuery = ajv.compile(CollectionsQuerySchema);\n if (!validateQuery(request.body)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const validDate = validateDateRange(\n request.body.fromDate as string,\n request.body.toDate as string,\n );\n if (!validDate?.isValid) {\n response.status(400).send(validDate);\n return;\n }\n\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const opts = request.body;\n\n // Act\n const collections = await database.getCollections(username, opts, {\n filters,\n postFilters,\n tagFilters,\n });\n\n await mapAdditionalFields(request, collections.collections, options, {\n checkRights: opts.checkAccess ?? false,\n username,\n });\n\n response.json(collections);\n });\n\n // POST /collections\n router.post(`/collections`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateCollectionPermission }],\n { throwOnDeny: true },\n );\n\n const username = await permissionMgr.getUsername(request);\n const created = await getCreated(request, options);\n\n // Act\n const collection = await database.createCollection({\n user_ref: username,\n title: request.body.title,\n description: request.body.description,\n created,\n images: request.body.images,\n headerImage: request.body.headerImage,\n tags: request.body.tags,\n entities: request.body.entities,\n users: request.body.users,\n opts: { includePosts: false },\n });\n\n if (!collection) {\n response\n .status(400)\n .send({ errors: 'Failed to create collection', type: 'body' });\n return;\n }\n\n wrapAsync(async () => {\n const followingUsers = await Promise.all([\n database.getFollowingUsers(username),\n ]);\n await notificationMgr.onNewCollection(\n username,\n collection,\n followingUsers.flat(),\n );\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'new_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'create-collection',\n severityLevel: 'medium',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n // Response\n response.status(201).json(collection);\n });\n\n // POST /collections/:id\n router.post(`/collections/:id`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n const originalCollection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!originalCollection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n {\n permission: qetaEditCollectionPermission,\n resource: originalCollection,\n },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n const collection = await database.updateCollection({\n id: collectionId,\n user_ref: username,\n title: request.body.title,\n description: request.body.description,\n images: request.body.images,\n headerImage: request.body.headerImage,\n tags: request.body.tags,\n entities: request.body.entities,\n users: request.body.users,\n opts: { postFilters, tagFilters, filters },\n });\n\n if (!collection) {\n response.sendStatus(401);\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'update-collection',\n severityLevel: 'medium',\n request,\n meta: {\n from: entityToJsonObject(originalCollection),\n to: entityToJsonObject(collection),\n },\n });\n\n // Response\n response.json(collection);\n });\n\n // DELETE /collections/:id\n router.delete('/collections/:id', async (request, response) => {\n // Validation\n const collectionId = Number.parseInt(request.params.id, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(collectionId) || !validateRequestBody(request.body)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n const username = await permissionMgr.getUsername(request);\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n // Act\n const deleted = await database.deleteCollection(collectionId);\n\n if (deleted && events) {\n events.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n reason: request.body.reason,\n },\n metadata: { action: 'delete_collection' },\n });\n }\n\n if (deleted) {\n notificationMgr.onCollectionDelete(\n username,\n collection,\n request.body.reason,\n );\n auditor?.createEvent({\n eventId: 'delete-collection',\n severityLevel: 'medium',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n reason: request.body.reason,\n },\n });\n }\n\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/collections/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const [postFilters, filters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n { allowServicePrincipal: true },\n ),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const collections = await database.getUserCollections(username, {\n filters,\n postFilters,\n tagFilters,\n });\n response.json(collections);\n });\n\n router.put('/collections/follow/:id', async (request, response) => {\n const { id } = request.params;\n const collectionId = Number.parseInt(id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n }\n\n const username = await permissionMgr.getUsername(request, false);\n const collection = await database.getCollection(username, collectionId);\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n await database.followCollection(username, collectionId);\n\n auditor?.createEvent({\n eventId: 'follow-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n response.status(204).send();\n });\n\n router.delete('/collections/follow/:id', async (request, response) => {\n const { id } = request.params;\n const collectionId = Number.parseInt(id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n }\n\n const username = await permissionMgr.getUsername(request, false);\n const collection = await database.getCollection(username, collectionId);\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n await database.unfollowCollection(username, collectionId);\n\n auditor?.createEvent({\n eventId: 'unfollow-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n response.status(204).send();\n });\n\n // GET /collections/:id\n router.get(`/collections/:id`, async (request, response) => {\n // Validation\n // Act\n const username = await permissionMgr.getUsername(request);\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n { postFilters, tagFilters },\n );\n\n if (collection === null) {\n response.sendStatus(404);\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadCollectionPermission, resource: collection }],\n { throwOnDeny: true },\n );\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'read-collection',\n severityLevel: 'low',\n request,\n meta: { collection: entityToJsonObject(collection) },\n });\n\n // Response\n response.json(collection);\n });\n\n // POST /collections/:id\n router.post(`/collections/:id/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n let collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n const post = await database.getPost(username, request.body.postId, false);\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection! },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n collection = await database.addPostToCollection(\n username,\n collectionId,\n request.body.postId,\n { postFilters, tagFilters },\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n wrapAsync(async () => {\n if (!collection) {\n return;\n }\n const followingUsers = await Promise.all([\n database.getUsersForCollection(collectionId),\n database.getFollowingUsers(username),\n ]);\n await notificationMgr.onNewPostToCollection(\n username,\n collection,\n followingUsers.flat(),\n );\n });\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'add-to-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n },\n });\n\n // Response\n response.status(200);\n response.json(collection);\n });\n\n // DELETE /collections/:id/posts\n router.delete(`/collections/:id/posts`, async (request, response) => {\n // Validation\n const validateRequestBody = ajv.compile(CollectionPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n let collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n const post = await database.getPost(username, request.body.postId, false);\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection! },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const [postFilters, tagFilters] = await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(request, qetaReadTagPermission, {\n allowServicePrincipal: true,\n }),\n ]);\n\n // Act\n collection = await database.removePostFromCollection(\n username,\n collectionId,\n request.body.postId,\n { postFilters, tagFilters },\n );\n\n if (!collection) {\n response\n .status(404)\n .send({ errors: 'Collection not found', type: 'body' });\n return;\n }\n\n events?.publish({\n topic: 'qeta',\n eventPayload: {\n collection,\n author: username,\n },\n metadata: { action: 'update_collection' },\n });\n\n await mapAdditionalFields(request, [collection], options, { username });\n\n auditor?.createEvent({\n eventId: 'delete-from-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n },\n });\n\n // Response\n response.status(200);\n response.json(collection);\n });\n\n router.post('/collections/:id/rank/', async (request, response) => {\n const validateRequestBody = ajv.compile(CollectionRankPostSchema);\n if (!validateRequestBody(request.body)) {\n response\n .status(400)\n .json({ errors: validateRequestBody.errors, type: 'body' });\n return;\n }\n\n const collectionId = Number.parseInt(request.params.id, 10);\n if (Number.isNaN(collectionId)) {\n response\n .status(400)\n .send({ errors: 'Invalid collection id', type: 'body' });\n return;\n }\n\n const username = await permissionMgr.getUsername(request);\n const collection = await database.getCollection(\n username,\n Number.parseInt(request.params.id, 10),\n );\n\n if (!collection) {\n response.sendStatus(404);\n return;\n }\n\n const post = await database.getPost(username, request.body.postId, false);\n\n if (!post) {\n response.status(404).send({ errors: 'Post not found', type: 'body' });\n return;\n }\n\n await permissionMgr.authorize(\n request,\n [\n { permission: qetaEditCollectionPermission, resource: collection },\n { permission: qetaReadPostPermission, resource: post },\n ],\n { throwOnDeny: true },\n );\n\n const currentRank = await database.getPostRank(\n collection.id,\n request.body.postId,\n );\n if (!currentRank) {\n response.status(404).send();\n return;\n }\n\n if (request.body.rank === 'up') {\n const higherRankPostId = await database.getNextRankedPostId(\n collection.id,\n request.body.postId,\n );\n if (higherRankPostId) {\n await database.updatePostRank(\n collection.id,\n higherRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n higherRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'down') {\n const lowerRankPostId = await database.getPreviousRankedPostId(\n collection.id,\n request.body.postId,\n );\n if (lowerRankPostId) {\n await database.updatePostRank(\n collection.id,\n lowerRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n lowerRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'top') {\n const topRankPostId = await database.getTopRankedPostId(collectionId);\n if (topRankPostId) {\n await database.updatePostRank(\n collection.id,\n topRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n topRankPostId.rank,\n );\n }\n } else if (request.body.rank === 'bottom') {\n const bottomRankPostId = await database.getBottomRankedPostId(\n collection.id,\n );\n if (bottomRankPostId) {\n await database.updatePostRank(\n collection.id,\n bottomRankPostId.postId,\n currentRank,\n );\n await database.updatePostRank(\n collection.id,\n request.body.postId,\n bottomRankPostId.rank,\n );\n }\n }\n\n auditor?.createEvent({\n eventId: 'rank-collection',\n severityLevel: 'low',\n request,\n meta: {\n collection: entityToJsonObject(collection),\n post: entityToJsonObject(post),\n rank: request.body.rank,\n },\n });\n\n response.sendStatus(200);\n });\n};\n"],"names":["Ajv","addFormats","CollectionsQuerySchema","validateDateRange","qetaReadPostPermission","qetaReadCollectionPermission","qetaReadTagPermission","mapAdditionalFields","CollectionSchema","qetaCreateCollectionPermission","getCreated","wrapAsync","entityToJsonObject","qetaEditCollectionPermission","DeleteMetadataSchema","qetaDeleteCollectionPermission","CollectionPostSchema","CollectionRankPostSchema"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var types = require('../types.cjs.js');
|
|
4
4
|
var util = require('../util.cjs.js');
|
|
5
|
+
var routeUtil = require('./routeUtil.cjs.js');
|
|
5
6
|
var catalogModel = require('@backstage/catalog-model');
|
|
6
7
|
var backstagePluginQetaCommon = require('@drodil/backstage-plugin-qeta-common');
|
|
7
8
|
var Ajv = require('ajv');
|
|
@@ -79,7 +80,15 @@ const helperRoutes = (router, options) => {
|
|
|
79
80
|
});
|
|
80
81
|
router.get("/users/followed", async (request, response) => {
|
|
81
82
|
const username = await permissionMgr.getUsername(request, false);
|
|
82
|
-
const
|
|
83
|
+
const key = `qeta:followed:users:${username}`;
|
|
84
|
+
const ttl = 24 * 60 * 60 * 1e3;
|
|
85
|
+
const users = await routeUtil.getCachedData(
|
|
86
|
+
options.cache,
|
|
87
|
+
key,
|
|
88
|
+
ttl,
|
|
89
|
+
() => database.getFollowedUsers(username),
|
|
90
|
+
options.logger
|
|
91
|
+
);
|
|
83
92
|
response.json(users);
|
|
84
93
|
});
|
|
85
94
|
router.put("/users/follow/:userRef(*)", async (request, response) => {
|
|
@@ -95,6 +104,7 @@ const helperRoutes = (router, options) => {
|
|
|
95
104
|
userRef
|
|
96
105
|
}
|
|
97
106
|
});
|
|
107
|
+
await options.cache?.delete(`qeta:followed:users:${username}`);
|
|
98
108
|
response.status(204).send();
|
|
99
109
|
});
|
|
100
110
|
router.delete("/users/follow/:userRef(*)", async (request, response) => {
|
|
@@ -110,6 +120,7 @@ const helperRoutes = (router, options) => {
|
|
|
110
120
|
userRef
|
|
111
121
|
}
|
|
112
122
|
});
|
|
123
|
+
await options.cache?.delete(`qeta:followed:users:${username}`);
|
|
113
124
|
response.status(204).send();
|
|
114
125
|
});
|
|
115
126
|
router.get("/tags", async (request, response) => {
|
|
@@ -137,7 +148,15 @@ const helperRoutes = (router, options) => {
|
|
|
137
148
|
backstagePluginQetaCommon.qetaReadTagPermission,
|
|
138
149
|
{ allowServicePrincipal: true }
|
|
139
150
|
);
|
|
140
|
-
const
|
|
151
|
+
const key = `qeta:followed:tags:${username}`;
|
|
152
|
+
const ttl = 24 * 60 * 60 * 1e3;
|
|
153
|
+
const tags = await routeUtil.getCachedData(
|
|
154
|
+
options.cache,
|
|
155
|
+
key,
|
|
156
|
+
ttl,
|
|
157
|
+
() => database.getUserTags(username, filter),
|
|
158
|
+
options.logger
|
|
159
|
+
);
|
|
141
160
|
response.json(tags);
|
|
142
161
|
});
|
|
143
162
|
router.put("/tags/follow/:tag", async (request, response) => {
|
|
@@ -152,6 +171,7 @@ const helperRoutes = (router, options) => {
|
|
|
152
171
|
tag
|
|
153
172
|
}
|
|
154
173
|
});
|
|
174
|
+
await options.cache?.delete(`qeta:followed:tags:${username}`);
|
|
155
175
|
response.status(204).send();
|
|
156
176
|
});
|
|
157
177
|
router.delete("/tags/follow/:tag", async (request, response) => {
|
|
@@ -166,6 +186,7 @@ const helperRoutes = (router, options) => {
|
|
|
166
186
|
tag
|
|
167
187
|
}
|
|
168
188
|
});
|
|
189
|
+
await options.cache?.delete(`qeta:followed:tags:${username}`);
|
|
169
190
|
response.status(204).send();
|
|
170
191
|
});
|
|
171
192
|
const getSuggestedTags = async (request, title, content, entities) => {
|
|
@@ -461,8 +482,16 @@ const helperRoutes = (router, options) => {
|
|
|
461
482
|
});
|
|
462
483
|
router.get("/entities/followed", async (request, response) => {
|
|
463
484
|
const username = await permissionMgr.getUsername(request, false);
|
|
464
|
-
const
|
|
465
|
-
|
|
485
|
+
const key = `qeta:followed:entities:${username}`;
|
|
486
|
+
const ttl = 24 * 60 * 60 * 1e3;
|
|
487
|
+
const entities = await routeUtil.getCachedData(
|
|
488
|
+
options.cache,
|
|
489
|
+
key,
|
|
490
|
+
ttl,
|
|
491
|
+
() => database.getUserEntities(username),
|
|
492
|
+
options.logger
|
|
493
|
+
);
|
|
494
|
+
response.json(entities);
|
|
466
495
|
});
|
|
467
496
|
router.get("/entities/links", async (request, response) => {
|
|
468
497
|
const credentials = await httpAuth.credentials(request, {
|
|
@@ -488,6 +517,7 @@ const helperRoutes = (router, options) => {
|
|
|
488
517
|
entityRef
|
|
489
518
|
}
|
|
490
519
|
});
|
|
520
|
+
await options.cache?.delete(`qeta:followed:entities:${username}`);
|
|
491
521
|
response.status(204).send();
|
|
492
522
|
});
|
|
493
523
|
router.delete("/entities/follow/:entityRef(*)", async (request, response) => {
|
|
@@ -503,6 +533,7 @@ const helperRoutes = (router, options) => {
|
|
|
503
533
|
entityRef
|
|
504
534
|
}
|
|
505
535
|
});
|
|
536
|
+
await options.cache?.delete(`qeta:followed:entities:${username}`);
|
|
506
537
|
response.status(204).send();
|
|
507
538
|
});
|
|
508
539
|
router.get("/entities/:entityRef(*)", async (request, response) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.cjs.js","sources":["../../../src/service/routes/helpers.ts"],"sourcesContent":["import { Request, Router } from 'express';\nimport {\n DeleteMetadataSchema,\n DraftQuestionSchema,\n EntitiesQuerySchema,\n RouteOptions,\n TagsQuerySchema,\n UsersQuerySchema,\n} from '../types';\nimport { mapAdditionalFields } from '../util';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n filterTags,\n getSupportedEntityKinds,\n isValidTag,\n qetaCreateTagPermission,\n qetaDeleteTagPermission,\n qetaEditTagPermission,\n qetaReadAnswerPermission,\n qetaReadCollectionPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n TagsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { eng, removeStopwords } from 'stopword';\nimport { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const helperRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n catalog,\n auth,\n config,\n httpAuth,\n auditor,\n logger,\n permissionMgr,\n aiHandler,\n } = options;\n\n const supportedKinds = getSupportedEntityKinds(config);\n\n const validateEntityRef = (entityRef: string, kind?: string) => {\n try {\n const valid = parseEntityRef(entityRef);\n if (\n kind &&\n valid.kind.toLocaleLowerCase('en-US') !==\n kind.toLocaleLowerCase('en-US')\n ) {\n throw new Error(`Expected kind: ${kind}`);\n }\n } catch (error) {\n throw new Error(`Invalid entityRef: ${entityRef}`);\n }\n };\n\n router.get('/users', async (request, response) => {\n const validateQuery = ajv.compile(UsersQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const users = await catalog.queryEntities(\n {\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = users.items\n .map(user => {\n try {\n return stringifyEntityRef(user);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const users = await database.getUsers({ entityRefs, ...request.query });\n response.json(users);\n });\n\n router.get('/users/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const users = await database.getFollowedUsers(username);\n response.json(users);\n });\n\n router.put('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.followUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'follow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n response.status(204).send();\n });\n\n router.delete('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'unfollow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n response.status(204).send();\n });\n\n // GET /tags\n router.get('/tags', async (request, response) => {\n const validateQuery = ajv.compile(TagsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n\n const opts = request.query as TagsQuery;\n const tags = await database.getTags(opts, filter);\n\n await mapAdditionalFields(request, tags.tags, options, {\n checkRights: opts.checkAccess ?? false,\n });\n\n response.json(tags);\n });\n\n router.get('/tags/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n const tags = await database.getUserTags(username, filter);\n\n response.json(tags);\n });\n\n router.put('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.followTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'follow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n\n response.status(204).send();\n });\n\n router.delete('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'unfollow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n response.status(204).send();\n });\n\n const getSuggestedTags = async (\n request: Request,\n title: string,\n content: string,\n entities?: string[],\n ) => {\n const suggestedTags: string[] = [];\n if (entities && entities.length > 0) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entityResponse = await catalog.getEntitiesByRefs(\n {\n entityRefs: entities,\n fields: ['metadata.tags'],\n filter: {\n 'metadata.tags': CATALOG_FILTER_EXISTS,\n },\n },\n { token },\n );\n const entityTags = entityResponse.items\n .flatMap(e => e?.metadata?.tags)\n .filter((t): t is string => !!t)\n .map(tag => tag.toLocaleLowerCase())\n .filter(filterTags)\n .slice(0, 5);\n suggestedTags.push(...entityTags);\n } catch (_error) {\n // Just ignore\n }\n }\n\n try {\n if (aiHandler?.suggestTags) {\n const { tags } = await aiHandler.suggestTags(title, content);\n suggestedTags.unshift(...tags);\n return [...new Set(suggestedTags)]\n .filter(filterTags)\n .map(tag => tag.toLocaleLowerCase())\n .slice(0, 10);\n }\n } catch (_error) {\n // NOOP: Fallback to database suggestions\n }\n\n const cleanWords = (words: string[]): string[] =>\n removeStopwords(words, [...eng]);\n\n const { tags: existingTags } = await database.getTags();\n\n const titleLower = title.toLocaleLowerCase();\n const titleWords = cleanWords(\n titleLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n const contentLower = content.toLocaleLowerCase();\n const contentWords = cleanWords(\n contentLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n\n existingTags.forEach(tag => {\n if (\n titleLower.includes(tag.tag.toLocaleLowerCase()) ||\n contentLower.includes(tag.tag.toLocaleLowerCase())\n ) {\n suggestedTags.push(tag.tag);\n return;\n }\n\n const descriptionWords = cleanWords(\n tag.description?.toLocaleLowerCase().split(/\\s+/) || [],\n );\n\n if (\n titleWords.some(word => descriptionWords.includes(word)) ||\n contentWords.some(word => descriptionWords.includes(word))\n ) {\n suggestedTags.push(tag.tag);\n }\n });\n\n return [...new Set(suggestedTags)].filter(filterTags).slice(0, 10);\n };\n\n router.post('/tags/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n const uniqueTags = [...new Set(allTags)];\n\n response.json({ tags: uniqueTags });\n } catch (error) {\n logger.error(`Failed to generate tag suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate tag suggestions' });\n }\n });\n\n router.get('/tags/:tag', async (request, response) => {\n const tag = await database.getTag(request.params.tag);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'read-tag',\n severityLevel: 'low',\n request,\n meta: { tagId: tag.id, tag: tag.tag },\n });\n response.json(tag);\n });\n\n router.post('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n if (Number.isNaN(tagId)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n const resp = await database.updateTag(tagId, description, experts);\n await mapAdditionalFields(request, resp ? [resp] : [], options);\n auditor?.createEvent({\n eventId: 'update-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...resp,\n tagId: tag.id,\n },\n });\n\n response.json(resp);\n });\n\n router.put('/tags', async (request, response) => {\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateTagPermission }],\n { throwOnDeny: true },\n );\n\n const existing = await database.getTag(request.body.tag);\n if (existing) {\n response.status(409).send({ errors: 'Tag already exists', type: 'body' });\n return;\n }\n\n if (!isValidTag(request.body.tag)) {\n response.status(400).send({ errors: 'Invalid tag', type: 'body' });\n return;\n }\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n\n const tag = await database.createTag(\n request.body.tag,\n description,\n experts,\n );\n if (!tag) {\n response.sendStatus(500);\n return;\n }\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'create-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...tag,\n tagId: tag.id,\n },\n });\n response.status(201).json(tag);\n });\n\n router.delete('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(tagId) || !validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteTagPermission, resource: tag! }],\n { throwOnDeny: true },\n );\n const deleted = await database.deleteTag(tagId);\n\n if (deleted) {\n auditor?.createEvent({\n eventId: 'delete-tag',\n severityLevel: 'medium',\n request,\n meta: {\n tagId,\n reason: request.body.reason,\n },\n });\n }\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/entities', async (request, response) => {\n const validateQuery = ajv.compile(EntitiesQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n kind: supportedKinds,\n },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = entities.items\n .map(entity => {\n try {\n return stringifyEntityRef(entity);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const entities = await database.getEntities({\n entityRefs,\n ...request.query,\n });\n response.json(entities);\n });\n\n router.post('/entities/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n if (!allTags.length) {\n response.json({ entities: [] });\n return;\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n 'metadata.tags': allTags,\n kind: supportedKinds,\n },\n },\n { token },\n );\n\n const notSetEntities = entities.items.filter(entity => {\n const ref = stringifyEntityRef(entity);\n return !request.body.entities?.includes(ref);\n });\n\n response.json({ entities: notSetEntities });\n } catch (error) {\n logger.error(`Failed to generate entity suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate entity suggestions' });\n }\n });\n\n router.get('/entities/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const tags = await database.getUserEntities(username);\n response.json(tags);\n });\n\n router.get('/entities/links', async (request, response) => {\n const credentials = await httpAuth.credentials(request, {\n allow: ['service'],\n });\n if (!credentials) {\n response.sendStatus(401);\n return;\n }\n\n const links = await database.getEntityLinks();\n response.json(links);\n });\n\n router.put('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.followEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'follow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n response.status(204).send();\n });\n\n router.delete('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'unfollow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n response.status(204).send();\n });\n\n router.get('/entities/:entityRef(*)', async (request, response) => {\n validateEntityRef(request.params.entityRef);\n const entity = await database.getEntity(request.params.entityRef);\n if (entity === null) {\n response.sendStatus(404);\n return;\n }\n auditor?.createEvent({\n eventId: 'read-entity',\n severityLevel: 'low',\n request,\n meta: { entityRef: request.params.entityRef },\n });\n response.json(entity);\n });\n\n // GET /timeline\n router.get(`/timeline`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n const limit = request.query.limit\n ? Number.parseInt(request.query.limit as string, 10)\n : 10;\n const offset = request.query.offset\n ? Number.parseInt(request.query.offset as string, 10)\n : 0;\n const includeTotal = request.query.includeTotal === 'true';\n\n const [filter, commentsFilter, answersFilter, collectionsFilter] =\n await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n ]);\n\n const timeline = await database.getTimeline(\n username,\n { limit, offset, includeTotal },\n {\n posts: filter,\n answers: answersFilter,\n comments: commentsFilter,\n collections: collectionsFilter,\n },\n );\n response.json(timeline);\n });\n};\n"],"names":["Ajv","addFormats","getSupportedEntityKinds","parseEntityRef","UsersQuerySchema","users","stringifyEntityRef","TagsQuerySchema","qetaReadTagPermission","mapAdditionalFields","CATALOG_FILTER_EXISTS","filterTags","removeStopwords","eng","DraftQuestionSchema","qetaEditTagPermission","qetaCreateTagPermission","isValidTag","DeleteMetadataSchema","qetaDeleteTagPermission","EntitiesQuerySchema","entities","qetaReadPostPermission","qetaReadCommentPermission","qetaReadAnswerPermission","qetaReadCollectionPermission"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"helpers.cjs.js","sources":["../../../src/service/routes/helpers.ts"],"sourcesContent":["import { Request, Router } from 'express';\nimport {\n DeleteMetadataSchema,\n DraftQuestionSchema,\n EntitiesQuerySchema,\n RouteOptions,\n TagsQuerySchema,\n UsersQuerySchema,\n} from '../types';\nimport { mapAdditionalFields } from '../util';\nimport { getCachedData } from './routeUtil';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n filterTags,\n getSupportedEntityKinds,\n isValidTag,\n qetaCreateTagPermission,\n qetaDeleteTagPermission,\n qetaEditTagPermission,\n qetaReadAnswerPermission,\n qetaReadCollectionPermission,\n qetaReadCommentPermission,\n qetaReadPostPermission,\n qetaReadTagPermission,\n TagsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { eng, removeStopwords } from 'stopword';\nimport { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client';\n\nconst ajv = new Ajv({ coerceTypes: 'array' });\naddFormats(ajv);\n\nexport const helperRoutes = (router: Router, options: RouteOptions) => {\n const {\n database,\n catalog,\n auth,\n config,\n httpAuth,\n auditor,\n logger,\n permissionMgr,\n aiHandler,\n } = options;\n\n const supportedKinds = getSupportedEntityKinds(config);\n\n const validateEntityRef = (entityRef: string, kind?: string) => {\n try {\n const valid = parseEntityRef(entityRef);\n if (\n kind &&\n valid.kind.toLocaleLowerCase('en-US') !==\n kind.toLocaleLowerCase('en-US')\n ) {\n throw new Error(`Expected kind: ${kind}`);\n }\n } catch (error) {\n throw new Error(`Invalid entityRef: ${entityRef}`);\n }\n };\n\n router.get('/users', async (request, response) => {\n const validateQuery = ajv.compile(UsersQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const users = await catalog.queryEntities(\n {\n filter: { kind: 'User' },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = users.items\n .map(user => {\n try {\n return stringifyEntityRef(user);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const users = await database.getUsers({ entityRefs, ...request.query });\n response.json(users);\n });\n\n router.get('/users/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:users:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const users = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getFollowedUsers(username),\n options.logger,\n );\n response.json(users);\n });\n\n router.put('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.followUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'follow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/users/follow/:userRef(*)', async (request, response) => {\n const { userRef } = request.params;\n validateEntityRef(userRef, 'user');\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowUser(username, userRef);\n\n auditor?.createEvent({\n eventId: 'unfollow-user',\n severityLevel: 'low',\n request,\n meta: {\n userRef,\n },\n });\n\n await options.cache?.delete(`qeta:followed:users:${username}`);\n\n response.status(204).send();\n });\n\n // GET /tags\n router.get('/tags', async (request, response) => {\n const validateQuery = ajv.compile(TagsQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n\n const opts = request.query as TagsQuery;\n const tags = await database.getTags(opts, filter);\n\n await mapAdditionalFields(request, tags.tags, options, {\n checkRights: opts.checkAccess ?? false,\n });\n\n response.json(tags);\n });\n\n router.get('/tags/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const filter = await permissionMgr.getAuthorizeConditions(\n request,\n qetaReadTagPermission,\n { allowServicePrincipal: true },\n );\n const key = `qeta:followed:tags:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const tags = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserTags(username, filter),\n options.logger,\n );\n\n response.json(tags);\n });\n\n router.put('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.followTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'follow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n\n response.status(204).send();\n });\n\n router.delete('/tags/follow/:tag', async (request, response) => {\n const { tag } = request.params;\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowTag(username, tag);\n\n auditor?.createEvent({\n eventId: 'unfollow-tag',\n severityLevel: 'low',\n request,\n meta: {\n tag,\n },\n });\n await options.cache?.delete(`qeta:followed:tags:${username}`);\n response.status(204).send();\n });\n\n const getSuggestedTags = async (\n request: Request,\n title: string,\n content: string,\n entities?: string[],\n ) => {\n const suggestedTags: string[] = [];\n if (entities && entities.length > 0) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entityResponse = await catalog.getEntitiesByRefs(\n {\n entityRefs: entities,\n fields: ['metadata.tags'],\n filter: {\n 'metadata.tags': CATALOG_FILTER_EXISTS,\n },\n },\n { token },\n );\n const entityTags = entityResponse.items\n .flatMap(e => e?.metadata?.tags)\n .filter((t): t is string => !!t)\n .map(tag => tag.toLocaleLowerCase())\n .filter(filterTags)\n .slice(0, 5);\n suggestedTags.push(...entityTags);\n } catch (_error) {\n // Just ignore\n }\n }\n\n try {\n if (aiHandler?.suggestTags) {\n const { tags } = await aiHandler.suggestTags(title, content);\n suggestedTags.unshift(...tags);\n return [...new Set(suggestedTags)]\n .filter(filterTags)\n .map(tag => tag.toLocaleLowerCase())\n .slice(0, 10);\n }\n } catch (_error) {\n // NOOP: Fallback to database suggestions\n }\n\n const cleanWords = (words: string[]): string[] =>\n removeStopwords(words, [...eng]);\n\n const { tags: existingTags } = await database.getTags();\n\n const titleLower = title.toLocaleLowerCase();\n const titleWords = cleanWords(\n titleLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n const contentLower = content.toLocaleLowerCase();\n const contentWords = cleanWords(\n contentLower.split(/\\s+/).map(word => word.toLocaleLowerCase()),\n );\n\n existingTags.forEach(tag => {\n if (\n titleLower.includes(tag.tag.toLocaleLowerCase()) ||\n contentLower.includes(tag.tag.toLocaleLowerCase())\n ) {\n suggestedTags.push(tag.tag);\n return;\n }\n\n const descriptionWords = cleanWords(\n tag.description?.toLocaleLowerCase().split(/\\s+/) || [],\n );\n\n if (\n titleWords.some(word => descriptionWords.includes(word)) ||\n contentWords.some(word => descriptionWords.includes(word))\n ) {\n suggestedTags.push(tag.tag);\n }\n });\n\n return [...new Set(suggestedTags)].filter(filterTags).slice(0, 10);\n };\n\n router.post('/tags/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n const uniqueTags = [...new Set(allTags)];\n\n response.json({ tags: uniqueTags });\n } catch (error) {\n logger.error(`Failed to generate tag suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate tag suggestions' });\n }\n });\n\n router.get('/tags/:tag', async (request, response) => {\n const tag = await database.getTag(request.params.tag);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaReadTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'read-tag',\n severityLevel: 'low',\n request,\n meta: { tagId: tag.id, tag: tag.tag },\n });\n response.json(tag);\n });\n\n router.post('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n if (Number.isNaN(tagId)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n if (!tag) {\n response.sendStatus(404);\n return;\n }\n await permissionMgr.authorize(\n request,\n [{ permission: qetaEditTagPermission, resource: tag }],\n { throwOnDeny: true },\n );\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n const resp = await database.updateTag(tagId, description, experts);\n await mapAdditionalFields(request, resp ? [resp] : [], options);\n auditor?.createEvent({\n eventId: 'update-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...resp,\n tagId: tag.id,\n },\n });\n\n response.json(resp);\n });\n\n router.put('/tags', async (request, response) => {\n await permissionMgr.authorize(\n request,\n [{ permission: qetaCreateTagPermission }],\n { throwOnDeny: true },\n );\n\n const existing = await database.getTag(request.body.tag);\n if (existing) {\n response.status(409).send({ errors: 'Tag already exists', type: 'body' });\n return;\n }\n\n if (!isValidTag(request.body.tag)) {\n response.status(400).send({ errors: 'Invalid tag', type: 'body' });\n return;\n }\n\n const description = request.body.description;\n const experts = request.body.experts;\n if (experts) {\n const isMod = await permissionMgr.isModerator(request);\n if (!isMod) {\n response.sendStatus(401);\n return;\n }\n }\n\n const tag = await database.createTag(\n request.body.tag,\n description,\n experts,\n );\n if (!tag) {\n response.sendStatus(500);\n return;\n }\n await mapAdditionalFields(request, [tag], options);\n auditor?.createEvent({\n eventId: 'create-tag',\n severityLevel: 'medium',\n request,\n meta: {\n ...tag,\n tagId: tag.id,\n },\n });\n response.status(201).json(tag);\n });\n\n router.delete('/tags/:tag', async (request, response) => {\n const tagId = Number.parseInt(request.params.tag, 10);\n const validateRequestBody = ajv.compile(DeleteMetadataSchema);\n if (Number.isNaN(tagId) || !validateRequestBody(request.body)) {\n response.status(400).send({ errors: 'Invalid tag id', type: 'body' });\n return;\n }\n\n const tag = await database.getTagById(tagId);\n await permissionMgr.authorize(\n request,\n [{ permission: qetaDeleteTagPermission, resource: tag! }],\n { throwOnDeny: true },\n );\n const deleted = await database.deleteTag(tagId);\n\n if (deleted) {\n auditor?.createEvent({\n eventId: 'delete-tag',\n severityLevel: 'medium',\n request,\n meta: {\n tagId,\n reason: request.body.reason,\n },\n });\n }\n // Response\n response.sendStatus(deleted ? 204 : 404);\n });\n\n router.get('/entities', async (request, response) => {\n const validateQuery = ajv.compile(EntitiesQuerySchema);\n if (!validateQuery(request.query)) {\n response\n .status(400)\n .send({ errors: validateQuery.errors, type: 'query' });\n return;\n }\n\n let entityRefs: string[] | undefined;\n if (request.query.searchQuery) {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n kind: supportedKinds,\n },\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n fullTextFilter: {\n term: String(request.query.searchQuery),\n fields: [\n 'metadata.name',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n ],\n },\n },\n { token },\n );\n entityRefs = entities.items\n .map(entity => {\n try {\n return stringifyEntityRef(entity);\n } catch (_e) {\n return null;\n }\n })\n .filter((e): e is string => e !== null);\n }\n\n const entities = await database.getEntities({\n entityRefs,\n ...request.query,\n });\n response.json(entities);\n });\n\n router.post('/entities/suggest', async (request, response) => {\n const validateRequestBody = ajv.compile(DraftQuestionSchema);\n if (!validateRequestBody(request.body)) {\n response.status(400).send({ errors: validateRequestBody.errors });\n return;\n }\n\n try {\n const suggestedTags = await getSuggestedTags(\n request,\n request.body.title,\n request.body.content,\n request.body.entities,\n );\n\n const allTags = request.body.tags\n ? [...new Set([...request.body.tags, ...suggestedTags])]\n : suggestedTags;\n\n if (!allTags.length) {\n response.json({ entities: [] });\n return;\n }\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await httpAuth.credentials(request),\n targetPluginId: 'catalog',\n });\n const entities = await catalog.queryEntities(\n {\n filter: {\n 'metadata.tags': allTags,\n kind: supportedKinds,\n },\n },\n { token },\n );\n\n const notSetEntities = entities.items.filter(entity => {\n const ref = stringifyEntityRef(entity);\n return !request.body.entities?.includes(ref);\n });\n\n response.json({ entities: notSetEntities });\n } catch (error) {\n logger.error(`Failed to generate entity suggestions: ${error}`);\n response\n .status(500)\n .json({ error: 'Failed to generate entity suggestions' });\n }\n });\n\n router.get('/entities/followed', async (request, response) => {\n const username = await permissionMgr.getUsername(request, false);\n const key = `qeta:followed:entities:${username}`;\n const ttl = 24 * 60 * 60 * 1000;\n const entities = await getCachedData(\n options.cache,\n key,\n ttl,\n () => database.getUserEntities(username),\n options.logger,\n );\n response.json(entities);\n });\n\n router.get('/entities/links', async (request, response) => {\n const credentials = await httpAuth.credentials(request, {\n allow: ['service'],\n });\n if (!credentials) {\n response.sendStatus(401);\n return;\n }\n\n const links = await database.getEntityLinks();\n response.json(links);\n });\n\n router.put('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.followEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'follow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.delete('/entities/follow/:entityRef(*)', async (request, response) => {\n const { entityRef } = request.params;\n validateEntityRef(entityRef);\n const username = await permissionMgr.getUsername(request, false);\n await database.unfollowEntity(username, entityRef);\n auditor?.createEvent({\n eventId: 'unfollow-entity',\n severityLevel: 'low',\n request,\n meta: {\n entityRef,\n },\n });\n await options.cache?.delete(`qeta:followed:entities:${username}`);\n response.status(204).send();\n });\n\n router.get('/entities/:entityRef(*)', async (request, response) => {\n validateEntityRef(request.params.entityRef);\n const entity = await database.getEntity(request.params.entityRef);\n if (entity === null) {\n response.sendStatus(404);\n return;\n }\n auditor?.createEvent({\n eventId: 'read-entity',\n severityLevel: 'low',\n request,\n meta: { entityRef: request.params.entityRef },\n });\n response.json(entity);\n });\n\n // GET /timeline\n router.get(`/timeline`, async (request, response) => {\n const username = await permissionMgr.getUsername(request, true);\n const limit = request.query.limit\n ? Number.parseInt(request.query.limit as string, 10)\n : 10;\n const offset = request.query.offset\n ? Number.parseInt(request.query.offset as string, 10)\n : 0;\n const includeTotal = request.query.includeTotal === 'true';\n\n const [filter, commentsFilter, answersFilter, collectionsFilter] =\n await Promise.all([\n permissionMgr.getAuthorizeConditions(request, qetaReadPostPermission, {\n allowServicePrincipal: true,\n }),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCommentPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadAnswerPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n permissionMgr.getAuthorizeConditions(\n request,\n qetaReadCollectionPermission,\n {\n allowServicePrincipal: true,\n },\n ),\n ]);\n\n const timeline = await database.getTimeline(\n username,\n { limit, offset, includeTotal },\n {\n posts: filter,\n answers: answersFilter,\n comments: commentsFilter,\n collections: collectionsFilter,\n },\n );\n response.json(timeline);\n });\n};\n"],"names":["Ajv","addFormats","getSupportedEntityKinds","parseEntityRef","UsersQuerySchema","users","stringifyEntityRef","getCachedData","TagsQuerySchema","qetaReadTagPermission","mapAdditionalFields","CATALOG_FILTER_EXISTS","filterTags","removeStopwords","eng","DraftQuestionSchema","qetaEditTagPermission","qetaCreateTagPermission","isValidTag","DeleteMetadataSchema","qetaDeleteTagPermission","EntitiesQuerySchema","entities","qetaReadPostPermission","qetaReadCommentPermission","qetaReadAnswerPermission","qetaReadCollectionPermission"],"mappings":"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"}
|
|
@@ -237,19 +237,29 @@ const postsRoutes = (router, options) => {
|
|
|
237
237
|
}
|
|
238
238
|
const opts = { ...request.query, ...optionOverride };
|
|
239
239
|
const [filter, tagsFilter, commentsFilter, answersFilter] = await getPostFilters(request, opts);
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
240
|
+
const key = `qeta:posts:list:${type}:${username}:${JSON.stringify(opts)}`;
|
|
241
|
+
const ttl = 300 * 1e3;
|
|
242
|
+
const posts = await routeUtil.getCachedData(
|
|
243
|
+
options.cache,
|
|
244
|
+
key,
|
|
245
|
+
ttl,
|
|
246
|
+
async () => {
|
|
247
|
+
return await database.getPosts(username, opts, filter, {
|
|
248
|
+
includeTotal: false,
|
|
249
|
+
includeAnswers: false,
|
|
250
|
+
includeAttachments: false,
|
|
251
|
+
includeEntities: false,
|
|
252
|
+
includeTags: false,
|
|
253
|
+
includeVotes: false,
|
|
254
|
+
includeExperts: false,
|
|
255
|
+
includeComments: false,
|
|
256
|
+
commentsFilter,
|
|
257
|
+
tagsFilter,
|
|
258
|
+
answersFilter
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
options.logger
|
|
262
|
+
);
|
|
253
263
|
await util$1.mapAdditionalFields(request, posts.posts, options, {
|
|
254
264
|
checkRights: opts.checkAccess ?? false,
|
|
255
265
|
username
|