diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts index 3c9137c77..543e87493 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts @@ -11,7 +11,8 @@ import { parseJson, parseTurtle, parseFile, - saveDatasetMeta + saveDatasetMeta, + checkUsernameExists } from '@semapps/middlewares'; import { ServiceSchema } from 'moleculer'; @@ -115,7 +116,7 @@ const ApiService = { }, methods: { getBoxesRoute(actorsPath) { - const middlewares = [ + let middlewares = [ parseUrl, parseHeader, negotiateContentType, @@ -127,6 +128,8 @@ const ApiService = { saveDatasetMeta ]; + if (this.settings.podProvider) middlewares.unshift(checkUsernameExists); + return { name: this.settings.podProvider ? 'boxes' : `boxes${actorsPath}`, path: actorsPath, diff --git a/src/middleware/packages/crypto/signature/proxy.ts b/src/middleware/packages/crypto/signature/proxy.ts index f0c5e4aee..1f964fa67 100644 --- a/src/middleware/packages/crypto/signature/proxy.ts +++ b/src/middleware/packages/crypto/signature/proxy.ts @@ -1,6 +1,6 @@ import path from 'path'; import urlJoin from 'url-join'; -import { parseHeader, parseFile, saveDatasetMeta } from '@semapps/middlewares'; +import { parseHeader, parseFile, saveDatasetMeta, checkUsernameExists } from '@semapps/middlewares'; import fetch from 'node-fetch'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; @@ -24,12 +24,15 @@ const ProxyService = { async started() { const basePath = await this.broker.call('ldp.getBasePath'); + let middlewares = [parseHeader, parseFile, saveDatasetMeta]; + if (this.settings.podProvider) middlewares.unshift(checkUsernameExists); + const routeConfig = { name: 'proxy-endpoint', authorization: true, authentication: false, aliases: { - 'POST /': [parseHeader, parseFile, saveDatasetMeta, 'signature.proxy.api_query'] // parseFile handles multipart/form-data + 'POST /': [...middlewares, 'signature.proxy.api_query'] // parseFile handles multipart/form-data } }; diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts b/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts index be83cc802..8c37e429c 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts @@ -1,10 +1,8 @@ -import { parseHeader, negotiateAccept, parseJson } from '@semapps/middlewares'; +import { parseHeader, negotiateAccept, parseJson, checkUsernameExists } from '@semapps/middlewares'; import path from 'node:path'; import { ServiceSchema } from 'moleculer'; import { VC_API_PATH } from '../constants'; -const middlewares = [parseHeader, parseJson, negotiateAccept]; - /** * * Verifiable Credentials API Service. @@ -30,6 +28,9 @@ const VCApiService = { const basePath = await this.broker.call('ldp.getBasePath'); const apiPath = path.join(basePath, this.settings.podProvider ? '/:username([^/.][^/]+)' : '', VC_API_PATH); + let middlewares = [parseHeader, parseJson, negotiateAccept]; + if (this.settings.podProvider) middlewares.unshift(checkUsernameExists); + // Credential routes. await this.broker.call('api.addRoute', { route: { diff --git a/src/middleware/packages/ldp/routes/getCatchAllRoute.ts b/src/middleware/packages/ldp/routes/getCatchAllRoute.ts index 95049886e..9b5725d50 100644 --- a/src/middleware/packages/ldp/routes/getCatchAllRoute.ts +++ b/src/middleware/packages/ldp/routes/getCatchAllRoute.ts @@ -9,11 +9,12 @@ import { parseJson, parseTurtle, parseFile, - saveDatasetMeta + saveDatasetMeta, + checkUsernameExists } from '@semapps/middlewares'; function getCatchAllRoute(basePath: any, podProvider: any) { - const middlewares = [ + let middlewares = [ parseUrl, parseHeader, negotiateContentType, @@ -25,6 +26,8 @@ function getCatchAllRoute(basePath: any, podProvider: any) { saveDatasetMeta ]; + if (podProvider) middlewares.unshift(checkUsernameExists); + return { name: 'ldp', path: path.join(basePath, podProvider ? '/:username([^/.][^/]+)/:slugParts*' : '/:slugParts([^/_][^/]+)*'), diff --git a/src/middleware/packages/ldp/routes/getPodsRoute.ts b/src/middleware/packages/ldp/routes/getPodsRoute.ts index 36874298c..b7a1b2585 100644 --- a/src/middleware/packages/ldp/routes/getPodsRoute.ts +++ b/src/middleware/packages/ldp/routes/getPodsRoute.ts @@ -9,7 +9,8 @@ import { parseJson, parseTurtle, parseFile, - saveDatasetMeta + saveDatasetMeta, + checkUsernameExists } from '@semapps/middlewares'; const transformRouteParamsToSlugParts = (req: any, res: any, next: any) => { @@ -26,7 +27,8 @@ const transformRouteParamsToSlugParts = (req: any, res: any, next: any) => { }; function getPodsRoute(basePath: any) { - const middlewares = [ + let middlewares = [ + checkUsernameExists, parseUrl, parseHeader, negotiateContentType, diff --git a/src/middleware/packages/middlewares/index.ts b/src/middleware/packages/middlewares/index.ts index 0267cecbf..1d148e07a 100644 --- a/src/middleware/packages/middlewares/index.ts +++ b/src/middleware/packages/middlewares/index.ts @@ -49,7 +49,7 @@ const throw403 = (msg: string) => { }; const throw404 = (msg: string) => { - throw new MoleculerError('Forbidden', 404, 'NOT_FOUND', { status: 'Not found', text: msg }); + throw new MoleculerError('Not found', 404, 'NOT_FOUND', { status: 'Not found', text: msg }); }; const throw500 = (msg: string) => { @@ -198,6 +198,23 @@ const saveDatasetMeta = (req: any, res: any, next: any) => { next(); }; +// To be used with a pod provider setting +const checkUsernameExists = async (req: any, res: any, next: any) => { + if (req.$params.username) { + const account = await req.$ctx.call('auth.account.findByUsername', { username: req.$params.username }); + if (!account) { + res.statusCode = 404; + res.statusCode = `User ${req.$params.username} not found`; + res.end(); + } else if (account.deletedAt) { + res.statusCode = 400; + res.statusCode = `User ${req.$params.username} has been deleted`; + res.end(); + } + } + next(); +}; + export { parseUrl, parseHeader, @@ -208,6 +225,7 @@ export { parseTurtle, parseFile, saveDatasetMeta, + checkUsernameExists, throw400, throw403, throw404, diff --git a/src/middleware/packages/sparql-endpoint/getRoute.ts b/src/middleware/packages/sparql-endpoint/getRoute.ts index 14b073919..9adcca504 100644 --- a/src/middleware/packages/sparql-endpoint/getRoute.ts +++ b/src/middleware/packages/sparql-endpoint/getRoute.ts @@ -1,7 +1,9 @@ -import { parseHeader, negotiateAccept, parseSparql, saveDatasetMeta } from '@semapps/middlewares'; -const middlewares = [parseHeader, parseSparql, negotiateAccept, saveDatasetMeta]; +import { parseHeader, negotiateAccept, parseSparql, saveDatasetMeta, checkUsernameExists } from '@semapps/middlewares'; + +function getRoute(path: any, podProvider: boolean) { + const middlewares = [parseHeader, parseSparql, negotiateAccept, saveDatasetMeta]; + if (podProvider) middlewares.unshift(checkUsernameExists); -function getRoute(path: any) { return { path, name: 'sparql-endpoint', diff --git a/src/middleware/packages/sparql-endpoint/service.ts b/src/middleware/packages/sparql-endpoint/service.ts index 74851cc2e..578b940ff 100644 --- a/src/middleware/packages/sparql-endpoint/service.ts +++ b/src/middleware/packages/sparql-endpoint/service.ts @@ -15,11 +15,14 @@ const SparqlEndpointService = { const basePath = await this.broker.call('ldp.getBasePath'); if (this.settings.podProvider) { await this.broker.call('api.addRoute', { - route: getRoute(path.join(basePath, '/:username([^/.][^/]+)/sparql')), + route: getRoute(path.join(basePath, '/:username([^/.][^/]+)/sparql'), this.settings.podProvider), toBottom: false }); } else { - await this.broker.call('api.addRoute', { route: getRoute(path.join(basePath, '/sparql')), toBottom: false }); + await this.broker.call('api.addRoute', { + route: getRoute(path.join(basePath, '/sparql'), this.settings.podProvider), + toBottom: false + }); } }, actions: {