@intlayer/backend 5.5.11 → 5.7.0
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/README.md +3 -0
- package/dist/cjs/controllers/ai.controller.cjs +10 -7
- package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
- package/dist/cjs/controllers/dictionary.controller.cjs +50 -58
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/controllers/eventListener.controller.cjs +2 -18
- package/dist/cjs/controllers/eventListener.controller.cjs.map +1 -1
- package/dist/cjs/controllers/newsletter.controller.cjs +38 -3
- package/dist/cjs/controllers/newsletter.controller.cjs.map +1 -1
- package/dist/cjs/controllers/oAuth2.controller.cjs +3 -3
- package/dist/cjs/controllers/oAuth2.controller.cjs.map +1 -1
- package/dist/cjs/controllers/organization.controller.cjs +92 -106
- package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
- package/dist/cjs/controllers/project.controller.cjs +81 -83
- package/dist/cjs/controllers/project.controller.cjs.map +1 -1
- package/dist/cjs/controllers/projectAccessKey.controller.cjs +30 -24
- package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
- package/dist/cjs/controllers/search.controller.cjs.map +1 -1
- package/dist/cjs/controllers/stripe.controller.cjs +4 -25
- package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
- package/dist/cjs/controllers/tag.controller.cjs +27 -16
- package/dist/cjs/controllers/tag.controller.cjs.map +1 -1
- package/dist/cjs/controllers/user.controller.cjs +88 -24
- package/dist/cjs/controllers/user.controller.cjs.map +1 -1
- package/dist/cjs/emails/InviteUserEmail.cjs +30 -12
- package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs +266 -0
- package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs.map +1 -0
- package/dist/cjs/emails/ResetUserPassword.cjs +27 -15
- package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
- package/dist/cjs/emails/ValidateUserEmail.cjs +27 -36
- package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/Welcome.cjs +27 -15
- package/dist/cjs/emails/Welcome.cjs.map +1 -1
- package/dist/cjs/emails/index.cjs +7 -5
- package/dist/cjs/emails/index.cjs.map +1 -1
- package/dist/cjs/export.cjs +2 -5
- package/dist/cjs/export.cjs.map +1 -1
- package/dist/cjs/index.cjs +61 -111
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/middlewares/oAuth2.middleware.cjs +26 -38
- package/dist/cjs/middlewares/oAuth2.middleware.cjs.map +1 -1
- package/dist/cjs/middlewares/request.middleware.cjs.map +1 -1
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs +17 -138
- package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
- package/dist/cjs/models/dictionary.model.cjs.map +1 -1
- package/dist/cjs/models/discussion.model.cjs.map +1 -1
- package/dist/cjs/models/oAuth2.model.cjs +4 -1
- package/dist/cjs/models/oAuth2.model.cjs.map +1 -1
- package/dist/cjs/models/organization.model.cjs +1 -4
- package/dist/cjs/models/organization.model.cjs.map +1 -1
- package/dist/cjs/models/project.model.cjs +4 -1
- package/dist/cjs/models/project.model.cjs.map +1 -1
- package/dist/cjs/models/session.model.cjs +34 -0
- package/dist/cjs/models/session.model.cjs.map +1 -0
- package/dist/cjs/models/tag.model.cjs.map +1 -1
- package/dist/cjs/models/user.model.cjs.map +1 -1
- package/dist/cjs/routes/ai.routes.cjs +3 -1
- package/dist/cjs/routes/ai.routes.cjs.map +1 -1
- package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
- package/dist/cjs/routes/eventListener.routes.cjs +1 -1
- package/dist/cjs/routes/eventListener.routes.cjs.map +1 -1
- package/dist/cjs/routes/newsletter.routes.cjs.map +1 -1
- package/dist/cjs/routes/organization.routes.cjs +8 -8
- package/dist/cjs/routes/organization.routes.cjs.map +1 -1
- package/dist/cjs/routes/project.routes.cjs +23 -14
- package/dist/cjs/routes/project.routes.cjs.map +1 -1
- package/dist/cjs/routes/search.routes.cjs.map +1 -1
- package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
- package/dist/cjs/routes/tags.routes.cjs +4 -4
- package/dist/cjs/routes/tags.routes.cjs.map +1 -1
- package/dist/cjs/routes/user.routes.cjs +12 -12
- package/dist/cjs/routes/user.routes.cjs.map +1 -1
- package/dist/cjs/schemas/dictionary.schema.cjs +18 -1
- package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
- package/dist/cjs/schemas/discussion.schema.cjs +18 -1
- package/dist/cjs/schemas/discussion.schema.cjs.map +1 -1
- package/dist/cjs/schemas/oAuth2.schema.cjs +18 -1
- package/dist/cjs/schemas/oAuth2.schema.cjs.map +1 -1
- package/dist/cjs/schemas/organization.schema.cjs +21 -1
- package/dist/cjs/schemas/organization.schema.cjs.map +1 -1
- package/dist/cjs/schemas/plans.schema.cjs +18 -1
- package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
- package/dist/cjs/schemas/project.schema.cjs +19 -14
- package/dist/cjs/schemas/project.schema.cjs.map +1 -1
- package/dist/cjs/schemas/session.schema.cjs +63 -0
- package/dist/cjs/schemas/session.schema.cjs.map +1 -0
- package/dist/cjs/schemas/tag.schema.cjs +18 -1
- package/dist/cjs/schemas/tag.schema.cjs.map +1 -1
- package/dist/cjs/schemas/user.schema.cjs +18 -48
- package/dist/cjs/schemas/user.schema.cjs.map +1 -1
- package/dist/cjs/services/dictionary.service.cjs +6 -5
- package/dist/cjs/services/dictionary.service.cjs.map +1 -1
- package/dist/cjs/services/email.service.cjs +13 -0
- package/dist/cjs/services/email.service.cjs.map +1 -1
- package/dist/cjs/services/oAuth2.service.cjs +49 -10
- package/dist/cjs/services/oAuth2.service.cjs.map +1 -1
- package/dist/cjs/services/organization.service.cjs +16 -15
- package/dist/cjs/services/organization.service.cjs.map +1 -1
- package/dist/cjs/services/project.service.cjs +1 -1
- package/dist/cjs/services/project.service.cjs.map +1 -1
- package/dist/cjs/services/projectAccessKey.service.cjs +17 -33
- package/dist/cjs/services/projectAccessKey.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +10 -10
- package/dist/cjs/services/subscription.service.cjs.map +1 -1
- package/dist/cjs/services/tag.service.cjs.map +1 -1
- package/dist/cjs/services/user.service.cjs +2 -42
- package/dist/cjs/services/user.service.cjs.map +1 -1
- package/dist/cjs/types/dictionary.types.cjs.map +1 -1
- package/dist/cjs/types/discussion.types.cjs.map +1 -1
- package/dist/cjs/types/oAuth2.types.cjs.map +1 -1
- package/dist/cjs/types/organization.types.cjs.map +1 -1
- package/dist/cjs/types/plan.types.cjs.map +1 -1
- package/dist/cjs/types/project.types.cjs.map +1 -1
- package/dist/cjs/types/session.types.cjs.map +1 -1
- package/dist/cjs/types/tag.types.cjs.map +1 -1
- package/dist/cjs/types/user.types.cjs.map +1 -1
- package/dist/cjs/utils/AI/aiSdk.cjs.map +1 -1
- package/dist/cjs/utils/AI/askDocQuestion/PROMPT.md +7 -1
- package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs +32 -14
- package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs.map +1 -1
- package/dist/cjs/utils/AI/askDocQuestion/embeddings.json +88086 -76800
- package/dist/cjs/utils/AI/autocomplete/PROMPT.md +18 -2
- package/dist/cjs/utils/AI/autocomplete/index.cjs +8 -5
- package/dist/cjs/utils/AI/autocomplete/index.cjs.map +1 -1
- package/dist/cjs/utils/access.cjs +2 -0
- package/dist/cjs/utils/access.cjs.map +1 -0
- package/dist/cjs/utils/accessControl.cjs +7 -0
- package/dist/cjs/utils/accessControl.cjs.map +1 -1
- package/dist/cjs/utils/auth/getAuth.cjs +248 -0
- package/dist/cjs/utils/auth/getAuth.cjs.map +1 -0
- package/dist/cjs/utils/cors.cjs +55 -0
- package/dist/cjs/utils/cors.cjs.map +1 -0
- package/dist/cjs/utils/ensureMongoDocumentToObject.cjs.map +1 -1
- package/dist/cjs/utils/errors/ErrorHandler.cjs +2 -2
- package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +114 -153
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs.map +1 -1
- package/dist/cjs/utils/filtersAndPagination/getProjectFiltersAndPagination.cjs.map +1 -1
- package/dist/cjs/utils/filtersAndPagination/getTagFiltersAndPagination.cjs.map +1 -1
- package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs +1 -1
- package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs.map +1 -1
- package/dist/cjs/utils/mapper/dictionary.cjs.map +1 -1
- package/dist/cjs/utils/mapper/organization.cjs +10 -8
- package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
- package/dist/cjs/utils/mapper/project.cjs +5 -18
- package/dist/cjs/utils/mapper/project.cjs.map +1 -1
- package/dist/cjs/utils/mapper/tag.cjs +4 -2
- package/dist/cjs/utils/mapper/tag.cjs.map +1 -1
- package/dist/cjs/utils/mapper/user.cjs +6 -3
- package/dist/cjs/utils/mapper/user.cjs.map +1 -1
- package/dist/cjs/utils/mergeFunctionTypes.cjs +17 -0
- package/dist/cjs/utils/mergeFunctionTypes.cjs.map +1 -0
- package/dist/cjs/utils/mongoDB/connectDB.cjs +3 -1
- package/dist/cjs/utils/mongoDB/connectDB.cjs.map +1 -1
- package/dist/cjs/utils/mongoDB/types.cjs +17 -0
- package/dist/cjs/utils/mongoDB/types.cjs.map +1 -0
- package/dist/cjs/utils/oAuth2.cjs.map +1 -1
- package/dist/cjs/utils/permissions.cjs +166 -0
- package/dist/cjs/utils/permissions.cjs.map +1 -0
- package/dist/cjs/utils/rateLimiter.cjs +88 -0
- package/dist/cjs/utils/rateLimiter.cjs.map +1 -0
- package/dist/esm/controllers/ai.controller.mjs +10 -7
- package/dist/esm/controllers/ai.controller.mjs.map +1 -1
- package/dist/esm/controllers/dictionary.controller.mjs +50 -58
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/controllers/eventListener.controller.mjs +2 -8
- package/dist/esm/controllers/eventListener.controller.mjs.map +1 -1
- package/dist/esm/controllers/newsletter.controller.mjs +38 -3
- package/dist/esm/controllers/newsletter.controller.mjs.map +1 -1
- package/dist/esm/controllers/oAuth2.controller.mjs +2 -2
- package/dist/esm/controllers/oAuth2.controller.mjs.map +1 -1
- package/dist/esm/controllers/organization.controller.mjs +95 -106
- package/dist/esm/controllers/organization.controller.mjs.map +1 -1
- package/dist/esm/controllers/project.controller.mjs +81 -83
- package/dist/esm/controllers/project.controller.mjs.map +1 -1
- package/dist/esm/controllers/projectAccessKey.controller.mjs +30 -24
- package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
- package/dist/esm/controllers/search.controller.mjs.map +1 -1
- package/dist/esm/controllers/stripe.controller.mjs +4 -25
- package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
- package/dist/esm/controllers/tag.controller.mjs +27 -16
- package/dist/esm/controllers/tag.controller.mjs.map +1 -1
- package/dist/esm/controllers/user.controller.mjs +85 -22
- package/dist/esm/controllers/user.controller.mjs.map +1 -1
- package/dist/esm/emails/InviteUserEmail.mjs +32 -14
- package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
- package/dist/esm/emails/OAuthTokenCreatedEmail.mjs +254 -0
- package/dist/esm/emails/OAuthTokenCreatedEmail.mjs.map +1 -0
- package/dist/esm/emails/ResetUserPassword.mjs +29 -17
- package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
- package/dist/esm/emails/ValidateUserEmail.mjs +29 -38
- package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
- package/dist/esm/emails/Welcome.mjs +29 -17
- package/dist/esm/emails/Welcome.mjs.map +1 -1
- package/dist/esm/emails/index.mjs +3 -2
- package/dist/esm/emails/index.mjs.map +1 -1
- package/dist/esm/export.mjs +1 -3
- package/dist/esm/export.mjs.map +1 -1
- package/dist/esm/index.mjs +60 -111
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/middlewares/oAuth2.middleware.mjs +27 -36
- package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
- package/dist/esm/middlewares/request.middleware.mjs.map +1 -1
- package/dist/esm/middlewares/sessionAuth.middleware.mjs +16 -127
- package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
- package/dist/esm/models/dictionary.model.mjs.map +1 -1
- package/dist/esm/models/discussion.model.mjs.map +1 -1
- package/dist/esm/models/oAuth2.model.mjs +4 -1
- package/dist/esm/models/oAuth2.model.mjs.map +1 -1
- package/dist/esm/models/organization.model.mjs +1 -4
- package/dist/esm/models/organization.model.mjs.map +1 -1
- package/dist/esm/models/project.model.mjs +4 -1
- package/dist/esm/models/project.model.mjs.map +1 -1
- package/dist/esm/models/session.model.mjs +10 -0
- package/dist/esm/models/session.model.mjs.map +1 -0
- package/dist/esm/models/tag.model.mjs.map +1 -1
- package/dist/esm/models/user.model.mjs.map +1 -1
- package/dist/esm/routes/ai.routes.mjs +3 -1
- package/dist/esm/routes/ai.routes.mjs.map +1 -1
- package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
- package/dist/esm/routes/eventListener.routes.mjs +1 -1
- package/dist/esm/routes/eventListener.routes.mjs.map +1 -1
- package/dist/esm/routes/newsletter.routes.mjs.map +1 -1
- package/dist/esm/routes/organization.routes.mjs +8 -8
- package/dist/esm/routes/organization.routes.mjs.map +1 -1
- package/dist/esm/routes/project.routes.mjs +23 -14
- package/dist/esm/routes/project.routes.mjs.map +1 -1
- package/dist/esm/routes/search.routes.mjs.map +1 -1
- package/dist/esm/routes/stripe.routes.mjs.map +1 -1
- package/dist/esm/routes/tags.routes.mjs +4 -4
- package/dist/esm/routes/tags.routes.mjs.map +1 -1
- package/dist/esm/routes/user.routes.mjs +14 -14
- package/dist/esm/routes/user.routes.mjs.map +1 -1
- package/dist/esm/schemas/dictionary.schema.mjs +18 -1
- package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
- package/dist/esm/schemas/discussion.schema.mjs +18 -1
- package/dist/esm/schemas/discussion.schema.mjs.map +1 -1
- package/dist/esm/schemas/oAuth2.schema.mjs +18 -1
- package/dist/esm/schemas/oAuth2.schema.mjs.map +1 -1
- package/dist/esm/schemas/organization.schema.mjs +21 -1
- package/dist/esm/schemas/organization.schema.mjs.map +1 -1
- package/dist/esm/schemas/plans.schema.mjs +18 -1
- package/dist/esm/schemas/plans.schema.mjs.map +1 -1
- package/dist/esm/schemas/project.schema.mjs +21 -15
- package/dist/esm/schemas/project.schema.mjs.map +1 -1
- package/dist/esm/schemas/session.schema.mjs +39 -0
- package/dist/esm/schemas/session.schema.mjs.map +1 -0
- package/dist/esm/schemas/tag.schema.mjs +21 -4
- package/dist/esm/schemas/tag.schema.mjs.map +1 -1
- package/dist/esm/schemas/user.schema.mjs +18 -48
- package/dist/esm/schemas/user.schema.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs +6 -5
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/services/email.service.mjs +33 -16
- package/dist/esm/services/email.service.mjs.map +1 -1
- package/dist/esm/services/oAuth2.service.mjs +47 -10
- package/dist/esm/services/oAuth2.service.mjs.map +1 -1
- package/dist/esm/services/organization.service.mjs +16 -14
- package/dist/esm/services/organization.service.mjs.map +1 -1
- package/dist/esm/services/project.service.mjs +1 -1
- package/dist/esm/services/project.service.mjs.map +1 -1
- package/dist/esm/services/projectAccessKey.service.mjs +15 -31
- package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +10 -10
- package/dist/esm/services/subscription.service.mjs.map +1 -1
- package/dist/esm/services/tag.service.mjs.map +1 -1
- package/dist/esm/services/user.service.mjs +2 -40
- package/dist/esm/services/user.service.mjs.map +1 -1
- package/dist/esm/types/user.types.mjs.map +1 -1
- package/dist/esm/utils/AI/aiSdk.mjs.map +1 -1
- package/dist/esm/utils/AI/askDocQuestion/PROMPT.md +7 -1
- package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs +32 -14
- package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -1
- package/dist/esm/utils/AI/askDocQuestion/embeddings.json +88086 -76800
- package/dist/esm/utils/AI/autocomplete/PROMPT.md +18 -2
- package/dist/esm/utils/AI/autocomplete/index.mjs +8 -5
- package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -1
- package/dist/esm/utils/access.mjs +1 -0
- package/dist/esm/utils/access.mjs.map +1 -0
- package/dist/esm/utils/accessControl.mjs +7 -0
- package/dist/esm/utils/accessControl.mjs.map +1 -1
- package/dist/esm/utils/auth/getAuth.mjs +227 -0
- package/dist/esm/utils/auth/getAuth.mjs.map +1 -0
- package/dist/esm/utils/cors.mjs +31 -0
- package/dist/esm/utils/cors.mjs.map +1 -0
- package/dist/esm/utils/ensureMongoDocumentToObject.mjs.map +1 -1
- package/dist/esm/utils/errors/ErrorHandler.mjs +2 -2
- package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +114 -153
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
- package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
- package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -1
- package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs +1 -1
- package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
- package/dist/esm/utils/mapper/dictionary.mjs.map +1 -1
- package/dist/esm/utils/mapper/organization.mjs +8 -7
- package/dist/esm/utils/mapper/organization.mjs.map +1 -1
- package/dist/esm/utils/mapper/project.mjs +5 -18
- package/dist/esm/utils/mapper/project.mjs.map +1 -1
- package/dist/esm/utils/mapper/tag.mjs +4 -2
- package/dist/esm/utils/mapper/tag.mjs.map +1 -1
- package/dist/esm/utils/mapper/user.mjs +6 -3
- package/dist/esm/utils/mapper/user.mjs.map +1 -1
- package/dist/esm/utils/mergeFunctionTypes.mjs +1 -0
- package/dist/esm/utils/mergeFunctionTypes.mjs.map +1 -0
- package/dist/esm/utils/mongoDB/connectDB.mjs +3 -1
- package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
- package/dist/esm/utils/mongoDB/types.mjs +1 -0
- package/dist/esm/utils/mongoDB/types.mjs.map +1 -0
- package/dist/esm/utils/oAuth2.mjs +3 -3
- package/dist/esm/utils/oAuth2.mjs.map +1 -1
- package/dist/esm/utils/permissions.mjs +138 -0
- package/dist/esm/utils/permissions.mjs.map +1 -0
- package/dist/esm/utils/rateLimiter.mjs +53 -0
- package/dist/esm/utils/rateLimiter.mjs.map +1 -0
- package/dist/types/controllers/ai.controller.d.ts +12 -10
- package/dist/types/controllers/ai.controller.d.ts.map +1 -1
- package/dist/types/controllers/dictionary.controller.d.ts +8 -9
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/controllers/eventListener.controller.d.ts +2 -3
- package/dist/types/controllers/eventListener.controller.d.ts.map +1 -1
- package/dist/types/controllers/newsletter.controller.d.ts +5 -6
- package/dist/types/controllers/newsletter.controller.d.ts.map +1 -1
- package/dist/types/controllers/oAuth2.controller.d.ts +3 -3
- package/dist/types/controllers/oAuth2.controller.d.ts.map +1 -1
- package/dist/types/controllers/organization.controller.d.ts +22 -23
- package/dist/types/controllers/organization.controller.d.ts.map +1 -1
- package/dist/types/controllers/project.controller.d.ts +13 -14
- package/dist/types/controllers/project.controller.d.ts.map +1 -1
- package/dist/types/controllers/projectAccessKey.controller.d.ts +5 -6
- package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
- package/dist/types/controllers/search.controller.d.ts +2 -3
- package/dist/types/controllers/search.controller.d.ts.map +1 -1
- package/dist/types/controllers/stripe.controller.d.ts +5 -6
- package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
- package/dist/types/controllers/tag.controller.d.ts +9 -10
- package/dist/types/controllers/tag.controller.d.ts.map +1 -1
- package/dist/types/controllers/user.controller.d.ts +16 -19
- package/dist/types/controllers/user.controller.d.ts.map +1 -1
- package/dist/types/emails/InviteUserEmail.d.ts.map +1 -1
- package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +21 -0
- package/dist/types/emails/OAuthTokenCreatedEmail.d.ts.map +1 -0
- package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
- package/dist/types/emails/Welcome.d.ts.map +1 -1
- package/dist/types/emails/index.d.ts +3 -2
- package/dist/types/emails/index.d.ts.map +1 -1
- package/dist/types/export.d.ts +2 -3
- package/dist/types/export.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/middlewares/oAuth2.middleware.d.ts +1 -2
- package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
- package/dist/types/middlewares/request.middleware.d.ts +3 -3
- package/dist/types/middlewares/request.middleware.d.ts.map +1 -1
- package/dist/types/middlewares/sessionAuth.middleware.d.ts +3 -25
- package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
- package/dist/types/models/dictionary.model.d.ts +6 -5
- package/dist/types/models/dictionary.model.d.ts.map +1 -1
- package/dist/types/models/discussion.model.d.ts +7 -2
- package/dist/types/models/discussion.model.d.ts.map +1 -1
- package/dist/types/models/oAuth2.model.d.ts +3 -2
- package/dist/types/models/oAuth2.model.d.ts.map +1 -1
- package/dist/types/models/organization.model.d.ts +2 -12
- package/dist/types/models/organization.model.d.ts.map +1 -1
- package/dist/types/models/project.model.d.ts +2 -11
- package/dist/types/models/project.model.d.ts.map +1 -1
- package/dist/types/models/session.model.d.ts +3 -0
- package/dist/types/models/session.model.d.ts.map +1 -0
- package/dist/types/models/tag.model.d.ts.map +1 -1
- package/dist/types/models/user.model.d.ts.map +1 -1
- package/dist/types/routes/ai.routes.d.ts.map +1 -1
- package/dist/types/routes/organization.routes.d.ts +4 -4
- package/dist/types/routes/project.routes.d.ts +4 -4
- package/dist/types/routes/project.routes.d.ts.map +1 -1
- package/dist/types/routes/tags.routes.d.ts +2 -2
- package/dist/types/routes/user.routes.d.ts +6 -7
- package/dist/types/routes/user.routes.d.ts.map +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts +6 -8
- package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
- package/dist/types/schemas/discussion.schema.d.ts +7 -5
- package/dist/types/schemas/discussion.schema.d.ts.map +1 -1
- package/dist/types/schemas/oAuth2.schema.d.ts +4 -3
- package/dist/types/schemas/oAuth2.schema.d.ts.map +1 -1
- package/dist/types/schemas/organization.schema.d.ts +6 -10
- package/dist/types/schemas/organization.schema.d.ts.map +1 -1
- package/dist/types/schemas/plans.schema.d.ts +6 -8
- package/dist/types/schemas/plans.schema.d.ts.map +1 -1
- package/dist/types/schemas/project.schema.d.ts +5 -17
- package/dist/types/schemas/project.schema.d.ts.map +1 -1
- package/dist/types/schemas/session.schema.d.ts +14 -0
- package/dist/types/schemas/session.schema.d.ts.map +1 -0
- package/dist/types/schemas/tag.schema.d.ts +6 -8
- package/dist/types/schemas/tag.schema.d.ts.map +1 -1
- package/dist/types/schemas/user.schema.d.ts +7 -5
- package/dist/types/schemas/user.schema.d.ts.map +1 -1
- package/dist/types/services/dictionary.service.d.ts +9 -9
- package/dist/types/services/dictionary.service.d.ts.map +1 -1
- package/dist/types/services/email.service.d.ts +4 -0
- package/dist/types/services/email.service.d.ts.map +1 -1
- package/dist/types/services/oAuth2.service.d.ts +23 -14
- package/dist/types/services/oAuth2.service.d.ts.map +1 -1
- package/dist/types/services/organization.service.d.ts +6 -12
- package/dist/types/services/organization.service.d.ts.map +1 -1
- package/dist/types/services/project.service.d.ts +5 -5
- package/dist/types/services/project.service.d.ts.map +1 -1
- package/dist/types/services/projectAccessKey.service.d.ts +5 -5
- package/dist/types/services/projectAccessKey.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +1 -1
- package/dist/types/services/subscription.service.d.ts.map +1 -1
- package/dist/types/services/tag.service.d.ts +6 -6
- package/dist/types/services/tag.service.d.ts.map +1 -1
- package/dist/types/services/user.service.d.ts +7 -21
- package/dist/types/services/user.service.d.ts.map +1 -1
- package/dist/types/types/dictionary.types.d.ts +11 -9
- package/dist/types/types/dictionary.types.d.ts.map +1 -1
- package/dist/types/types/discussion.types.d.ts +5 -2
- package/dist/types/types/discussion.types.d.ts.map +1 -1
- package/dist/types/types/oAuth2.types.d.ts +5 -2
- package/dist/types/types/oAuth2.types.d.ts.map +1 -1
- package/dist/types/types/organization.types.d.ts +11 -8
- package/dist/types/types/organization.types.d.ts.map +1 -1
- package/dist/types/types/plan.types.d.ts +6 -3
- package/dist/types/types/plan.types.d.ts.map +1 -1
- package/dist/types/types/project.types.d.ts +25 -25
- package/dist/types/types/project.types.d.ts.map +1 -1
- package/dist/types/types/session.types.d.ts +31 -17
- package/dist/types/types/session.types.d.ts.map +1 -1
- package/dist/types/types/tag.types.d.ts +8 -6
- package/dist/types/types/tag.types.d.ts.map +1 -1
- package/dist/types/types/user.types.d.ts +14 -21
- package/dist/types/types/user.types.d.ts.map +1 -1
- package/dist/types/utils/AI/aiSdk.d.ts +2 -2
- package/dist/types/utils/AI/aiSdk.d.ts.map +1 -1
- package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts +2 -0
- package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -1
- package/dist/types/utils/AI/autocomplete/index.d.ts +4 -1
- package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -1
- package/dist/types/utils/access.d.ts +1 -0
- package/dist/types/utils/access.d.ts.map +1 -0
- package/dist/types/utils/accessControl.d.ts +9 -9
- package/dist/types/utils/accessControl.d.ts.map +1 -1
- package/dist/types/utils/auth/getAuth.d.ts +7 -0
- package/dist/types/utils/auth/getAuth.d.ts.map +1 -0
- package/dist/types/utils/cors.d.ts +3 -0
- package/dist/types/utils/cors.d.ts.map +1 -0
- package/dist/types/utils/ensureMongoDocumentToObject.d.ts +2 -2
- package/dist/types/utils/ensureMongoDocumentToObject.d.ts.map +1 -1
- package/dist/types/utils/errors/ErrorHandler.d.ts +1 -1
- package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +57 -96
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts +1 -1
- package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
- package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts +1 -1
- package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
- package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +1 -1
- package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -1
- package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts +1 -1
- package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
- package/dist/types/utils/mapper/dictionary.d.ts +1 -1
- package/dist/types/utils/mapper/dictionary.d.ts.map +1 -1
- package/dist/types/utils/mapper/organization.d.ts +3 -2
- package/dist/types/utils/mapper/organization.d.ts.map +1 -1
- package/dist/types/utils/mapper/project.d.ts +4 -5
- package/dist/types/utils/mapper/project.d.ts.map +1 -1
- package/dist/types/utils/mapper/tag.d.ts +1 -1
- package/dist/types/utils/mapper/tag.d.ts.map +1 -1
- package/dist/types/utils/mapper/user.d.ts +2 -2
- package/dist/types/utils/mapper/user.d.ts.map +1 -1
- package/dist/types/utils/mergeFunctionTypes.d.ts +18 -0
- package/dist/types/utils/mergeFunctionTypes.d.ts.map +1 -0
- package/dist/types/utils/mongoDB/connectDB.d.ts +1 -1
- package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
- package/dist/types/utils/mongoDB/types.d.ts +11 -0
- package/dist/types/utils/mongoDB/types.d.ts.map +1 -0
- package/dist/types/utils/permissions.d.ts +115 -0
- package/dist/types/utils/permissions.d.ts.map +1 -0
- package/dist/types/utils/rateLimiter.d.ts +4 -0
- package/dist/types/utils/rateLimiter.d.ts.map +1 -0
- package/package.json +16 -14
- package/dist/cjs/controllers/sessionAuth.controller.cjs +0 -839
- package/dist/cjs/controllers/sessionAuth.controller.cjs.map +0 -1
- package/dist/cjs/routes/sessionAuth.routes.cjs +0 -154
- package/dist/cjs/routes/sessionAuth.routes.cjs.map +0 -1
- package/dist/cjs/services/sessionAuth.service.cjs +0 -385
- package/dist/cjs/services/sessionAuth.service.cjs.map +0 -1
- package/dist/cjs/utils/CSRF.cjs +0 -50
- package/dist/cjs/utils/CSRF.cjs.map +0 -1
- package/dist/cjs/utils/cookies.cjs +0 -59
- package/dist/cjs/utils/cookies.cjs.map +0 -1
- package/dist/esm/controllers/sessionAuth.controller.mjs +0 -790
- package/dist/esm/controllers/sessionAuth.controller.mjs.map +0 -1
- package/dist/esm/routes/sessionAuth.routes.mjs +0 -142
- package/dist/esm/routes/sessionAuth.routes.mjs.map +0 -1
- package/dist/esm/services/sessionAuth.service.mjs +0 -337
- package/dist/esm/services/sessionAuth.service.mjs.map +0 -1
- package/dist/esm/utils/CSRF.mjs +0 -24
- package/dist/esm/utils/CSRF.mjs.map +0 -1
- package/dist/esm/utils/cookies.mjs +0 -32
- package/dist/esm/utils/cookies.mjs.map +0 -1
- package/dist/types/controllers/sessionAuth.controller.d.ts +0 -140
- package/dist/types/controllers/sessionAuth.controller.d.ts.map +0 -1
- package/dist/types/routes/sessionAuth.routes.d.ts +0 -77
- package/dist/types/routes/sessionAuth.routes.d.ts.map +0 -1
- package/dist/types/services/sessionAuth.service.d.ts +0 -141
- package/dist/types/services/sessionAuth.service.d.ts.map +0 -1
- package/dist/types/utils/CSRF.d.ts +0 -3
- package/dist/types/utils/CSRF.d.ts.map +0 -1
- package/dist/types/utils/cookies.d.ts +0 -12
- package/dist/types/utils/cookies.d.ts.map +0 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { logger } from "./../logger/index.mjs";
|
|
2
|
+
import { SessionModel } from "./../models/session.model.mjs";
|
|
2
3
|
import * as projectService from "./../services/project.service.mjs";
|
|
3
|
-
import * as sessionAuthService from "./../services/sessionAuth.service.mjs";
|
|
4
4
|
import * as userService from "./../services/user.service.mjs";
|
|
5
5
|
import { ErrorHandler } from "./../utils/errors/index.mjs";
|
|
6
6
|
import {
|
|
7
7
|
getProjectFiltersAndPagination
|
|
8
8
|
} from "./../utils/filtersAndPagination/getProjectFiltersAndPagination.mjs";
|
|
9
9
|
import { mapProjectsToAPI, mapProjectToAPI } from "./../utils/mapper/project.mjs";
|
|
10
|
+
import { hasPermission } from "./../utils/permissions.mjs";
|
|
10
11
|
import { getPLanDetails } from "./../utils/plan.mjs";
|
|
11
12
|
import {
|
|
12
13
|
formatPaginatedResponse,
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
} from "./../utils/responseData.mjs";
|
|
15
16
|
import { t } from "express-intlayer";
|
|
16
17
|
const getProjects = async (req, res, _next) => {
|
|
17
|
-
const { user, organization,
|
|
18
|
+
const { user, organization, roles } = res.locals;
|
|
18
19
|
const { filters, pageSize, skip, page, getNumberOfPages } = getProjectFiltersAndPagination(req);
|
|
19
20
|
if (!user) {
|
|
20
21
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
@@ -24,14 +25,14 @@ const getProjects = async (req, res, _next) => {
|
|
|
24
25
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
|
-
if (!
|
|
28
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
28
|
+
if (!hasPermission(roles, "project:read")(res.locals)) {
|
|
29
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
const restrictedFilter = {
|
|
32
33
|
...filters,
|
|
33
|
-
membersIds: { $in: [...filters.membersIds ?? [], String(user.
|
|
34
|
-
organizationId: String(organization.
|
|
34
|
+
membersIds: { $in: [...filters.membersIds ?? [], String(user.id)] },
|
|
35
|
+
organizationId: String(organization.id)
|
|
35
36
|
};
|
|
36
37
|
try {
|
|
37
38
|
const projects = await projectService.findProjects(
|
|
@@ -40,11 +41,7 @@ const getProjects = async (req, res, _next) => {
|
|
|
40
41
|
pageSize
|
|
41
42
|
);
|
|
42
43
|
const totalItems = await projectService.countProjects(filters);
|
|
43
|
-
const formattedProjects = mapProjectsToAPI(
|
|
44
|
-
projects,
|
|
45
|
-
user,
|
|
46
|
-
res.locals.isProjectAdmin
|
|
47
|
-
);
|
|
44
|
+
const formattedProjects = mapProjectsToAPI(projects);
|
|
48
45
|
const responseData = formatPaginatedResponse({
|
|
49
46
|
data: formattedProjects,
|
|
50
47
|
page,
|
|
@@ -60,7 +57,7 @@ const getProjects = async (req, res, _next) => {
|
|
|
60
57
|
}
|
|
61
58
|
};
|
|
62
59
|
const addProject = async (req, res, _next) => {
|
|
63
|
-
const { organization, user,
|
|
60
|
+
const { organization, user, roles } = res.locals;
|
|
64
61
|
const projectData = req.body;
|
|
65
62
|
if (!user) {
|
|
66
63
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
@@ -70,42 +67,40 @@ const addProject = async (req, res, _next) => {
|
|
|
70
67
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
71
68
|
return;
|
|
72
69
|
}
|
|
73
|
-
if (!isOrganizationAdmin) {
|
|
74
|
-
ErrorHandler.handleGenericErrorResponse(
|
|
75
|
-
res,
|
|
76
|
-
"USER_IS_NOT_ADMIN_OF_ORGANIZATION"
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
70
|
if (!projectData) {
|
|
80
71
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
|
|
81
72
|
}
|
|
73
|
+
if (!hasPermission(roles, "project:admin")()) {
|
|
74
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
82
77
|
const { plan } = organization;
|
|
83
78
|
const planType = getPLanDetails(plan);
|
|
84
79
|
if (planType.numberOfProjects) {
|
|
85
80
|
const projectCount = await projectService.countProjects({
|
|
86
|
-
organizationId: organization.
|
|
81
|
+
organizationId: organization.id
|
|
87
82
|
});
|
|
88
83
|
if (projectCount >= planType.numberOfProjects) {
|
|
89
84
|
ErrorHandler.handleGenericErrorResponse(
|
|
90
85
|
res,
|
|
91
86
|
"PLAN_PROJECT_LIMIT_REACHED",
|
|
92
87
|
{
|
|
93
|
-
organizationId: organization.
|
|
88
|
+
organizationId: organization.id
|
|
94
89
|
}
|
|
95
90
|
);
|
|
96
91
|
return;
|
|
97
92
|
}
|
|
98
93
|
}
|
|
99
94
|
const project = {
|
|
100
|
-
membersIds: [user.
|
|
101
|
-
adminsIds: [user.
|
|
102
|
-
creatorId: user.
|
|
103
|
-
organizationId: organization.
|
|
95
|
+
membersIds: [user.id],
|
|
96
|
+
adminsIds: [user.id],
|
|
97
|
+
creatorId: user.id,
|
|
98
|
+
organizationId: organization.id,
|
|
104
99
|
...projectData
|
|
105
100
|
};
|
|
106
101
|
try {
|
|
107
102
|
const newProject = await projectService.createProject(project);
|
|
108
|
-
const formattedProject = mapProjectToAPI(newProject
|
|
103
|
+
const formattedProject = mapProjectToAPI(newProject);
|
|
109
104
|
const responseData = formatResponse({
|
|
110
105
|
message: t({
|
|
111
106
|
en: "Project created successfully",
|
|
@@ -127,7 +122,7 @@ const addProject = async (req, res, _next) => {
|
|
|
127
122
|
}
|
|
128
123
|
};
|
|
129
124
|
const updateProject = async (req, res, _next) => {
|
|
130
|
-
const { organization,
|
|
125
|
+
const { organization, project, user, roles } = res.locals;
|
|
131
126
|
const projectData = req.body;
|
|
132
127
|
if (!user) {
|
|
133
128
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
@@ -141,28 +136,20 @@ const updateProject = async (req, res, _next) => {
|
|
|
141
136
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
142
137
|
return;
|
|
143
138
|
}
|
|
144
|
-
if (
|
|
145
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (!projectRights?.write) {
|
|
149
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_RIGHTS_NOT_WRITE");
|
|
139
|
+
if (String(project.organizationId) !== String(organization.id)) {
|
|
140
|
+
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_IN_ORGANIZATION");
|
|
150
141
|
return;
|
|
151
142
|
}
|
|
152
|
-
if (
|
|
153
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
143
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
144
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
154
145
|
return;
|
|
155
146
|
}
|
|
156
147
|
try {
|
|
157
148
|
const updatedProject = await projectService.updateProjectById(
|
|
158
|
-
project.
|
|
149
|
+
project.id,
|
|
159
150
|
projectData
|
|
160
151
|
);
|
|
161
|
-
const formattedProject = mapProjectToAPI(
|
|
162
|
-
updatedProject,
|
|
163
|
-
user,
|
|
164
|
-
isProjectAdmin
|
|
165
|
-
);
|
|
152
|
+
const formattedProject = mapProjectToAPI(updatedProject);
|
|
166
153
|
const responseData = formatResponse({
|
|
167
154
|
message: t({
|
|
168
155
|
en: "Project updated successfully",
|
|
@@ -184,7 +171,7 @@ const updateProject = async (req, res, _next) => {
|
|
|
184
171
|
}
|
|
185
172
|
};
|
|
186
173
|
const updateProjectMembers = async (req, res, _next) => {
|
|
187
|
-
const { user, project,
|
|
174
|
+
const { user, project, organization, roles } = res.locals;
|
|
188
175
|
const { membersIds } = req.body;
|
|
189
176
|
if (!user) {
|
|
190
177
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
@@ -194,17 +181,6 @@ const updateProjectMembers = async (req, res, _next) => {
|
|
|
194
181
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
195
182
|
return;
|
|
196
183
|
}
|
|
197
|
-
if (!isProjectAdmin) {
|
|
198
|
-
ErrorHandler.handleGenericErrorResponse(
|
|
199
|
-
res,
|
|
200
|
-
"USER_IS_NOT_ADMIN_OF_PROJECT"
|
|
201
|
-
);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
if (!projectRights?.admin) {
|
|
205
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_RIGHTS_NOT_ADMIN");
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
184
|
if (!organization) {
|
|
209
185
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
210
186
|
return;
|
|
@@ -217,6 +193,10 @@ const updateProjectMembers = async (req, res, _next) => {
|
|
|
217
193
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_MUST_HAVE_ADMIN");
|
|
218
194
|
return;
|
|
219
195
|
}
|
|
196
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
197
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
220
200
|
try {
|
|
221
201
|
const existingUsers = [];
|
|
222
202
|
if (membersIds) {
|
|
@@ -231,29 +211,25 @@ const updateProjectMembers = async (req, res, _next) => {
|
|
|
231
211
|
const userMap = users.map((user2) => ({
|
|
232
212
|
user: user2,
|
|
233
213
|
isAdmin: membersIds.find(
|
|
234
|
-
(member) => String(member.userId) === String(user2.
|
|
214
|
+
(member) => String(member.userId) === String(user2.id)
|
|
235
215
|
)?.isAdmin ?? false
|
|
236
216
|
}));
|
|
237
217
|
existingUsers.push(...userMap);
|
|
238
218
|
}
|
|
239
219
|
}
|
|
240
220
|
const formattedMembers = existingUsers.map(
|
|
241
|
-
(user2) => user2.user.
|
|
221
|
+
(user2) => user2.user.id
|
|
242
222
|
);
|
|
243
|
-
const formattedAdmin = existingUsers.filter((el) => el.isAdmin).map((user2) => user2.user.
|
|
223
|
+
const formattedAdmin = existingUsers.filter((el) => el.isAdmin).map((user2) => user2.user.id);
|
|
244
224
|
const updatedOrganization = await projectService.updateProjectById(
|
|
245
|
-
project.
|
|
225
|
+
project.id,
|
|
246
226
|
{
|
|
247
227
|
...project,
|
|
248
228
|
membersIds: formattedMembers,
|
|
249
229
|
adminsIds: formattedAdmin
|
|
250
230
|
}
|
|
251
231
|
);
|
|
252
|
-
const formattedProject = mapProjectToAPI(
|
|
253
|
-
updatedOrganization,
|
|
254
|
-
user,
|
|
255
|
-
isProjectAdmin
|
|
256
|
-
);
|
|
232
|
+
const formattedProject = mapProjectToAPI(updatedOrganization);
|
|
257
233
|
const responseData = formatResponse({
|
|
258
234
|
message: t({
|
|
259
235
|
en: "Project members updated successfully",
|
|
@@ -275,7 +251,7 @@ const updateProjectMembers = async (req, res, _next) => {
|
|
|
275
251
|
}
|
|
276
252
|
};
|
|
277
253
|
const pushProjectConfiguration = async (req, res, _next) => {
|
|
278
|
-
const { user, project } = res.locals;
|
|
254
|
+
const { user, project, roles } = res.locals;
|
|
279
255
|
const projectConfiguration = req.body;
|
|
280
256
|
if (!user) {
|
|
281
257
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
@@ -285,13 +261,17 @@ const pushProjectConfiguration = async (req, res, _next) => {
|
|
|
285
261
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
286
262
|
return;
|
|
287
263
|
}
|
|
264
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
265
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
288
268
|
try {
|
|
289
|
-
const projectObject = await projectService.getProjectById(project.
|
|
269
|
+
const projectObject = await projectService.getProjectById(project.id);
|
|
290
270
|
projectObject.configuration = projectConfiguration;
|
|
291
271
|
projectObject.save();
|
|
292
272
|
if (!projectObject.configuration) {
|
|
293
273
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_UPDATE_FAILED", {
|
|
294
|
-
projectId: project.
|
|
274
|
+
projectId: project.id
|
|
295
275
|
});
|
|
296
276
|
return;
|
|
297
277
|
}
|
|
@@ -316,7 +296,7 @@ const pushProjectConfiguration = async (req, res, _next) => {
|
|
|
316
296
|
}
|
|
317
297
|
};
|
|
318
298
|
const deleteProject = async (_req, res, _next) => {
|
|
319
|
-
const { user, organization, project,
|
|
299
|
+
const { user, organization, project, session, roles } = res.locals;
|
|
320
300
|
if (!user) {
|
|
321
301
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
322
302
|
return;
|
|
@@ -329,32 +309,31 @@ const deleteProject = async (_req, res, _next) => {
|
|
|
329
309
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
330
310
|
return;
|
|
331
311
|
}
|
|
332
|
-
if (!
|
|
333
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
312
|
+
if (!session) {
|
|
313
|
+
ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (!hasPermission(roles, "project:admin")()) {
|
|
317
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
334
318
|
return;
|
|
335
319
|
}
|
|
336
320
|
try {
|
|
337
|
-
const projectToDelete = await projectService.getProjectById(project.
|
|
338
|
-
if (String(projectToDelete.organizationId) !== String(organization.
|
|
321
|
+
const projectToDelete = await projectService.getProjectById(project.id);
|
|
322
|
+
if (String(projectToDelete.organizationId) !== String(organization.id)) {
|
|
339
323
|
ErrorHandler.handleGenericErrorResponse(
|
|
340
324
|
res,
|
|
341
325
|
"PROJECT_NOT_IN_ORGANIZATION"
|
|
342
326
|
);
|
|
343
327
|
return;
|
|
344
328
|
}
|
|
345
|
-
const deletedProject = await projectService.deleteProjectById(project.
|
|
329
|
+
const deletedProject = await projectService.deleteProjectById(project.id);
|
|
346
330
|
if (!deletedProject) {
|
|
347
331
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED", {
|
|
348
|
-
projectId: project.
|
|
332
|
+
projectId: project.id
|
|
349
333
|
});
|
|
350
334
|
return;
|
|
351
335
|
}
|
|
352
|
-
logger.info(`Project deleted: ${String(deletedProject.
|
|
353
|
-
const formattedProject = mapProjectToAPI(
|
|
354
|
-
deletedProject,
|
|
355
|
-
user,
|
|
356
|
-
isProjectAdmin
|
|
357
|
-
);
|
|
336
|
+
logger.info(`Project deleted: ${String(deletedProject.id)}`);
|
|
358
337
|
const responseData = formatResponse({
|
|
359
338
|
message: t({
|
|
360
339
|
en: "Project deleted successfully",
|
|
@@ -366,9 +345,12 @@ const deleteProject = async (_req, res, _next) => {
|
|
|
366
345
|
fr: "Votre projet a \xE9t\xE9 supprim\xE9 avec succ\xE8s",
|
|
367
346
|
es: "Su proyecto ha sido eliminado con \xE9xito"
|
|
368
347
|
}),
|
|
369
|
-
data:
|
|
348
|
+
data: mapProjectToAPI(deletedProject)
|
|
370
349
|
});
|
|
371
|
-
|
|
350
|
+
await SessionModel.updateOne(
|
|
351
|
+
{ _id: session.id },
|
|
352
|
+
{ $set: { activeProjectId: null } }
|
|
353
|
+
);
|
|
372
354
|
res.json(responseData);
|
|
373
355
|
return;
|
|
374
356
|
} catch (error) {
|
|
@@ -378,13 +360,21 @@ const deleteProject = async (_req, res, _next) => {
|
|
|
378
360
|
};
|
|
379
361
|
const selectProject = async (req, res, _next) => {
|
|
380
362
|
const { projectId } = req.params;
|
|
363
|
+
const { session, roles } = res.locals;
|
|
381
364
|
if (!projectId) {
|
|
382
365
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_ID_NOT_FOUND");
|
|
383
366
|
return;
|
|
384
367
|
}
|
|
368
|
+
if (!session) {
|
|
369
|
+
ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
385
372
|
try {
|
|
386
373
|
const project = await projectService.getProjectById(projectId);
|
|
387
|
-
|
|
374
|
+
await SessionModel.updateOne(
|
|
375
|
+
{ _id: session.id },
|
|
376
|
+
{ $set: { activeProjectId: String(projectId) } }
|
|
377
|
+
);
|
|
388
378
|
const responseData = formatResponse({
|
|
389
379
|
message: t({
|
|
390
380
|
en: "Project selected successfully",
|
|
@@ -396,7 +386,7 @@ const selectProject = async (req, res, _next) => {
|
|
|
396
386
|
fr: "Votre projet a \xE9t\xE9 s\xE9lectionn\xE9 avec succ\xE8s",
|
|
397
387
|
es: "Su proyecto ha sido seleccionado con \xE9xito"
|
|
398
388
|
}),
|
|
399
|
-
data: project
|
|
389
|
+
data: mapProjectToAPI(project)
|
|
400
390
|
});
|
|
401
391
|
res.json(responseData);
|
|
402
392
|
return;
|
|
@@ -405,9 +395,17 @@ const selectProject = async (req, res, _next) => {
|
|
|
405
395
|
return;
|
|
406
396
|
}
|
|
407
397
|
};
|
|
408
|
-
const unselectProject = (_req, res, _next) => {
|
|
398
|
+
const unselectProject = async (_req, res, _next) => {
|
|
399
|
+
const { session } = res.locals;
|
|
400
|
+
if (!session) {
|
|
401
|
+
ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
409
404
|
try {
|
|
410
|
-
|
|
405
|
+
await SessionModel.updateOne(
|
|
406
|
+
{ _id: session.id },
|
|
407
|
+
{ $set: { activeProjectId: null } }
|
|
408
|
+
);
|
|
411
409
|
const responseData = formatResponse({
|
|
412
410
|
message: t({
|
|
413
411
|
en: "Project unselected successfully",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/project.controller.ts"],"sourcesContent":["import type {\n Project,\n ProjectAPI,\n ProjectConfiguration,\n ProjectCreationData,\n ProjectData,\n} from '@/types/project.types';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport * as projectService from '@services/project.service';\nimport * as sessionAuthService from '@services/sessionAuth.service';\nimport * as userService from '@services/user.service';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getProjectFiltersAndPagination,\n type ProjectFilters,\n type ProjectFiltersParams,\n} from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport { mapProjectsToAPI, mapProjectToAPI } from '@utils/mapper/project';\nimport { getPLanDetails } from '@utils/plan';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport { t } from 'express-intlayer';\nimport type { ObjectId } from 'mongoose';\nimport type { User } from 'oauth2-server';\n\nexport type GetProjectsParams = FiltersAndPagination<ProjectFiltersParams>;\nexport type GetProjectsResult = PaginatedResponse<ProjectAPI>;\n\n/**\n * Retrieves a list of projects based on filters and pagination.\n */\nexport const getProjects = async (\n req: Request<GetProjectsParams>,\n res: ResponseWithInformation<GetProjectsResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, projectRights } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getProjectFiltersAndPagination(req);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!projectRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_RIGHTS_NOT_READ');\n return;\n }\n\n const restrictedFilter: ProjectFilters = {\n ...filters,\n membersIds: { $in: [...(filters.membersIds ?? []), String(user._id)] },\n organizationId: String(organization._id),\n };\n\n try {\n const projects = await projectService.findProjects(\n restrictedFilter,\n skip,\n pageSize\n );\n const totalItems = await projectService.countProjects(filters);\n\n const formattedProjects = mapProjectsToAPI(\n projects,\n user,\n res.locals.isProjectAdmin\n );\n\n const responseData = formatPaginatedResponse<ProjectAPI>({\n data: formattedProjects,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddProjectBody = ProjectCreationData;\nexport type AddProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Adds a new project to the database.\n */\nexport const addProject = async (\n req: Request<any, any, AddProjectBody>,\n res: ResponseWithInformation<AddProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, user, isOrganizationAdmin } = res.locals;\n const projectData = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!isOrganizationAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_ORGANIZATION'\n );\n }\n\n if (!projectData) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_DATA_NOT_FOUND');\n }\n\n const { plan } = organization;\n\n const planType = getPLanDetails(plan);\n\n if (planType.numberOfProjects) {\n const projectCount = await projectService.countProjects({\n organizationId: organization._id,\n });\n\n if (projectCount >= planType.numberOfProjects) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'PLAN_PROJECT_LIMIT_REACHED',\n {\n organizationId: organization._id,\n }\n );\n return;\n }\n }\n\n const project: ProjectData = {\n membersIds: [user._id],\n adminsIds: [user._id],\n creatorId: user._id,\n organizationId: organization._id,\n ...projectData,\n };\n\n try {\n const newProject = await projectService.createProject(project);\n\n const formattedProject = mapProjectToAPI(newProject, user, true);\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project created successfully',\n fr: 'Projet créé avec succès',\n es: 'Proyecto creado con éxito',\n }),\n description: t({\n en: 'Your project has been created successfully',\n fr: 'Votre projet a été créé avec succès',\n es: 'Su proyecto ha sido creado con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateProjectBody = Partial<Project>;\nexport type UpdateProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Updates an existing project in the database.\n */\nexport const updateProject = async (\n req: Request<any, any, UpdateProjectBody>,\n res: ResponseWithInformation<UpdateProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, projectRights, project, user, isProjectAdmin } =\n res.locals;\n const projectData = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_DATA_NOT_FOUND');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!isProjectAdmin) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_RIGHTS_NOT_ADMIN');\n return;\n }\n\n if (!projectRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_RIGHTS_NOT_WRITE');\n return;\n }\n\n if (String(project.organizationId) !== String(organization._id)) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_IN_ORGANIZATION');\n return;\n }\n\n try {\n const updatedProject = await projectService.updateProjectById(\n project._id,\n projectData\n );\n\n const formattedProject = mapProjectToAPI(\n updatedProject,\n user,\n isProjectAdmin\n );\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project updated successfully',\n fr: 'Projet mis à jour avec succès',\n es: 'Proyecto actualizado con éxito',\n }),\n description: t({\n en: 'Your project has been updated successfully',\n fr: 'Votre projet a été mis à jour avec succès',\n es: 'Su proyecto ha sido actualizado con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\ntype UserAndAdmin = { user: User; isAdmin: boolean };\nexport type ProjectMemberByIdOption = {\n userId: string | ObjectId;\n isAdmin?: boolean;\n};\n\nexport type UpdateProjectMembersBody = Partial<{\n membersIds: ProjectMemberByIdOption[];\n}>;\nexport type UpdateProjectMembersResult = ResponseData<ProjectAPI>;\n\n/**\n * Update members to the dictionary in the database.\n */\nexport const updateProjectMembers = async (\n req: Request<any, any, UpdateProjectMembersBody>,\n res: ResponseWithInformation<UpdateProjectMembersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, isProjectAdmin, organization, projectRights } =\n res.locals;\n const { membersIds } = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!isProjectAdmin) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'USER_IS_NOT_ADMIN_OF_PROJECT'\n );\n return;\n }\n\n if (!projectRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_RIGHTS_NOT_ADMIN');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (membersIds?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_MUST_HAVE_MEMBER');\n return;\n }\n\n if (membersIds?.map((el) => el.isAdmin)?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_MUST_HAVE_ADMIN');\n return;\n }\n\n try {\n const existingUsers: UserAndAdmin[] = [];\n\n if (membersIds) {\n const userIdList = membersIds\n ?.filter(\n (member) =>\n // Remove members that are not in the organization\n !organization?.membersIds.includes(member.userId as ObjectId)\n )\n .map((member) => member.userId);\n\n const users = await userService.getUsersByIds(userIdList);\n\n if (users) {\n const userMap: UserAndAdmin[] = users.map((user) => ({\n user,\n isAdmin:\n membersIds.find(\n (member) => String(member.userId) === String(user._id)\n )?.isAdmin ?? false,\n }));\n\n existingUsers.push(...userMap);\n }\n }\n\n const formattedMembers: ObjectId[] = existingUsers.map(\n (user) => user.user._id\n );\n const formattedAdmin: ObjectId[] = existingUsers\n .filter((el) => el.isAdmin)\n .map((user) => user.user._id);\n\n const updatedOrganization = await projectService.updateProjectById(\n project._id,\n {\n ...project,\n membersIds: formattedMembers,\n adminsIds: formattedAdmin,\n }\n );\n\n const formattedProject = mapProjectToAPI(\n updatedOrganization,\n user,\n isProjectAdmin\n );\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project members updated successfully',\n fr: 'Membres du projet mis à jour avec succès',\n es: 'Miembros del proyecto actualizados con éxito',\n }),\n description: t({\n en: 'Your project members have been updated successfully',\n fr: 'Les membres de votre projet ont été mis à jour avec succès',\n es: 'Los miembros de su proyecto han sido actualizados con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushProjectConfigurationBody = ProjectConfiguration;\nexport type PushProjectConfigurationResult = ResponseData<ProjectConfiguration>;\n\n/**\n * Pushes a project configuration to the database.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response confirming the deletion.\n */\nexport const pushProjectConfiguration = async (\n req: Request<any, any, PushProjectConfigurationBody>,\n res: ResponseWithInformation<PushProjectConfigurationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project } = res.locals;\n const projectConfiguration = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n try {\n const projectObject = await projectService.getProjectById(project._id);\n projectObject.configuration = projectConfiguration;\n\n projectObject.save();\n\n if (!projectObject.configuration) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_UPDATE_FAILED', {\n projectId: project._id,\n });\n return;\n }\n\n const responseData = formatResponse<ProjectConfiguration>({\n message: t({\n en: 'Project configuration updated successfully',\n fr: 'Configuration du projet mise à jour avec succès',\n es: 'Configuración del proyecto actualizada con éxito',\n }),\n description: t({\n en: 'Your project configuration has been updated successfully',\n fr: 'La configuration du projet a été mise à jour avec succès',\n es: 'Su configuración del proyecto ha sido actualizada con éxito',\n }),\n data: projectObject.configuration,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Deletes a project from the database by its ID.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response confirming the deletion.\n */\nexport const deleteProject = async (\n _req: Request,\n res: ResponseWithInformation<DeleteProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, project, projectRights, isProjectAdmin } =\n res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!projectRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const projectToDelete = await projectService.getProjectById(project._id);\n\n if (String(projectToDelete.organizationId) !== String(organization._id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'PROJECT_NOT_IN_ORGANIZATION'\n );\n return;\n }\n\n const deletedProject = await projectService.deleteProjectById(project._id);\n\n if (!deletedProject) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED', {\n projectId: project._id,\n });\n\n return;\n }\n\n logger.info(`Project deleted: ${String(deletedProject._id)}`);\n\n const formattedProject = mapProjectToAPI(\n deletedProject,\n user,\n isProjectAdmin\n );\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project deleted successfully',\n fr: 'Projet supprimé avec succès',\n es: 'Proyecto eliminado con éxito',\n }),\n description: t({\n en: 'Your project has been deleted successfully',\n fr: 'Votre projet a été supprimé avec succès',\n es: 'Su proyecto ha sido eliminado con éxito',\n }),\n data: formattedProject,\n });\n\n sessionAuthService.clearProjectAuth(res);\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type SelectProjectParam = { projectId: ObjectId | string };\nexport type SelectProjectResult = ResponseData<Project>;\n\n/**\n * Select a project.\n */\nexport const selectProject = async (\n req: Request<SelectProjectParam>,\n res: ResponseWithInformation<SelectProjectResult>,\n _next: NextFunction\n) => {\n const { projectId } = req.params;\n\n if (!projectId) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_ID_NOT_FOUND');\n return;\n }\n\n try {\n const project = await projectService.getProjectById(projectId);\n\n sessionAuthService.setProjectAuth(res, project);\n\n const responseData = formatResponse<Project>({\n message: t({\n en: 'Project selected successfully',\n fr: 'Projet sélectionné avec succès',\n es: 'Proyecto seleccionado con éxito',\n }),\n description: t({\n en: 'Your project has been selected successfully',\n fr: 'Votre projet a été sélectionné avec succès',\n es: 'Su proyecto ha sido seleccionado con éxito',\n }),\n data: project,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UnselectProjectResult = ResponseData<null>;\n\n/**\n * Unselect a project.\n */\nexport const unselectProject = (\n _req: Request,\n res: ResponseWithInformation<UnselectProjectResult>,\n _next: NextFunction\n) => {\n try {\n sessionAuthService.clearProjectAuth(res);\n\n const responseData = formatResponse<null>({\n message: t({\n en: 'Project unselected successfully',\n fr: 'Projet désélectionné avec succès',\n es: 'Proyecto deseleccionado con éxito',\n }),\n description: t({\n en: 'Your project has been unselected successfully',\n fr: 'Votre projet a été désélectionné avec succès',\n es: 'Su proyecto ha sido deseleccionado con éxito',\n }),\n data: null,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":["user"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/project.controller.ts"],"sourcesContent":["import type {\n Project,\n ProjectAPI,\n ProjectConfiguration,\n ProjectCreationData,\n ProjectData,\n} from '@/types/project.types';\nimport type { User } from '@/types/user.types';\nimport { logger } from '@logger';\nimport { SessionModel } from '@models/session.model';\nimport * as projectService from '@services/project.service';\nimport * as userService from '@services/user.service';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getProjectFiltersAndPagination,\n type ProjectFilters,\n type ProjectFiltersParams,\n} from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport { mapProjectsToAPI, mapProjectToAPI } from '@utils/mapper/project';\nimport { hasPermission } from '@utils/permissions';\nimport { getPLanDetails } from '@utils/plan';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\nimport { t } from 'express-intlayer';\nimport { Types } from 'mongoose';\n\nexport type GetProjectsParams = FiltersAndPagination<ProjectFiltersParams>;\nexport type GetProjectsResult = PaginatedResponse<ProjectAPI>;\n\n/**\n * Retrieves a list of projects based on filters and pagination.\n */\nexport const getProjects = async (\n req: Request<GetProjectsParams>,\n res: Response<GetProjectsResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, roles } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getProjectFiltersAndPagination(req);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!hasPermission(roles, 'project:read')(res.locals)) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n const restrictedFilter: ProjectFilters = {\n ...filters,\n membersIds: { $in: [...(filters.membersIds ?? []), String(user.id)] },\n organizationId: String(organization.id),\n };\n\n try {\n const projects = await projectService.findProjects(\n restrictedFilter,\n skip,\n pageSize\n );\n const totalItems = await projectService.countProjects(filters);\n\n const formattedProjects = mapProjectsToAPI(projects);\n\n const responseData = formatPaginatedResponse<ProjectAPI>({\n data: formattedProjects,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddProjectBody = ProjectCreationData;\nexport type AddProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Adds a new project to the database.\n */\nexport const addProject = async (\n req: Request<any, any, AddProjectBody>,\n res: Response<AddProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, user, roles } = res.locals;\n const projectData = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!projectData) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_DATA_NOT_FOUND');\n }\n\n if (!hasPermission(roles, 'project:admin')()) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n const { plan } = organization;\n\n const planType = getPLanDetails(plan);\n\n if (planType.numberOfProjects) {\n const projectCount = await projectService.countProjects({\n organizationId: organization.id,\n });\n\n if (projectCount >= planType.numberOfProjects) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'PLAN_PROJECT_LIMIT_REACHED',\n {\n organizationId: organization.id,\n }\n );\n return;\n }\n }\n\n const project: ProjectData = {\n membersIds: [user.id],\n adminsIds: [user.id],\n creatorId: user.id,\n organizationId: organization.id,\n ...projectData,\n };\n\n try {\n const newProject = await projectService.createProject(project);\n\n const formattedProject = mapProjectToAPI(newProject);\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project created successfully',\n fr: 'Projet créé avec succès',\n es: 'Proyecto creado con éxito',\n }),\n description: t({\n en: 'Your project has been created successfully',\n fr: 'Votre projet a été créé avec succès',\n es: 'Su proyecto ha sido creado con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateProjectBody = Partial<Project>;\nexport type UpdateProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Updates an existing project in the database.\n */\nexport const updateProject = async (\n req: Request<any, any, UpdateProjectBody>,\n res: Response<UpdateProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, project, user, roles } = res.locals;\n const projectData = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_DATA_NOT_FOUND');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (String(project.organizationId) !== String(organization.id)) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_IN_ORGANIZATION');\n return;\n }\n\n if (!hasPermission(roles, 'project:write')()) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n try {\n const updatedProject = await projectService.updateProjectById(\n project.id,\n projectData\n );\n\n const formattedProject = mapProjectToAPI(updatedProject);\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project updated successfully',\n fr: 'Projet mis à jour avec succès',\n es: 'Proyecto actualizado con éxito',\n }),\n description: t({\n en: 'Your project has been updated successfully',\n fr: 'Votre projet a été mis à jour avec succès',\n es: 'Su proyecto ha sido actualizado con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\ntype UserAndAdmin = { user: User; isAdmin: boolean };\nexport type ProjectMemberByIdOption = {\n userId: string | Types.ObjectId;\n isAdmin?: boolean;\n};\n\nexport type UpdateProjectMembersBody = Partial<{\n membersIds: ProjectMemberByIdOption[];\n}>;\nexport type UpdateProjectMembersResult = ResponseData<ProjectAPI>;\n\n/**\n * Update members to the dictionary in the database.\n */\nexport const updateProjectMembers = async (\n req: Request<any, any, UpdateProjectMembersBody>,\n res: Response<UpdateProjectMembersResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, organization, roles } = res.locals;\n const { membersIds } = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (membersIds?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_MUST_HAVE_MEMBER');\n return;\n }\n\n if (membersIds?.map((el) => el.isAdmin)?.length === 0) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_MUST_HAVE_ADMIN');\n return;\n }\n\n if (!hasPermission(roles, 'project:write')()) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n try {\n const existingUsers: UserAndAdmin[] = [];\n\n if (membersIds) {\n const userIdList = membersIds\n ?.filter(\n (member) =>\n // Remove members that are not in the organization\n !organization?.membersIds.includes(member.userId as Types.ObjectId)\n )\n .map((member) => member.userId);\n\n const users = await userService.getUsersByIds(userIdList);\n\n if (users) {\n const userMap: UserAndAdmin[] = users.map((user) => ({\n user,\n isAdmin:\n membersIds.find(\n (member) => String(member.userId) === String(user.id)\n )?.isAdmin ?? false,\n }));\n\n existingUsers.push(...userMap);\n }\n }\n\n const formattedMembers: Types.ObjectId[] = existingUsers.map(\n (user) => user.user.id\n );\n const formattedAdmin: Types.ObjectId[] = existingUsers\n .filter((el) => el.isAdmin)\n .map((user) => user.user.id);\n\n const updatedOrganization = await projectService.updateProjectById(\n project.id,\n {\n ...project,\n membersIds: formattedMembers,\n adminsIds: formattedAdmin,\n }\n );\n\n const formattedProject = mapProjectToAPI(updatedOrganization);\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project members updated successfully',\n fr: 'Membres du projet mis à jour avec succès',\n es: 'Miembros del proyecto actualizados con éxito',\n }),\n description: t({\n en: 'Your project members have been updated successfully',\n fr: 'Les membres de votre projet ont été mis à jour avec succès',\n es: 'Los miembros de su proyecto han sido actualizados con éxito',\n }),\n data: formattedProject,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushProjectConfigurationBody = ProjectConfiguration;\nexport type PushProjectConfigurationResult = ResponseData<ProjectConfiguration>;\n\n/**\n * Pushes a project configuration to the database.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response confirming the deletion.\n */\nexport const pushProjectConfiguration = async (\n req: Request<any, any, PushProjectConfigurationBody>,\n res: Response<PushProjectConfigurationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, roles } = res.locals;\n const projectConfiguration = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!hasPermission(roles, 'project:write')()) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n try {\n const projectObject = await projectService.getProjectById(project.id);\n projectObject.configuration = projectConfiguration;\n\n projectObject.save();\n\n if (!projectObject.configuration) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_UPDATE_FAILED', {\n projectId: project.id,\n });\n return;\n }\n\n const responseData = formatResponse<ProjectConfiguration>({\n message: t({\n en: 'Project configuration updated successfully',\n fr: 'Configuration du projet mise à jour avec succès',\n es: 'Configuración del proyecto actualizada con éxito',\n }),\n description: t({\n en: 'Your project configuration has been updated successfully',\n fr: 'La configuration du projet a été mise à jour avec succès',\n es: 'Su configuración del proyecto ha sido actualizada con éxito',\n }),\n data: projectObject.configuration,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Deletes a project from the database by its ID.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response confirming the deletion.\n */\nexport const deleteProject = async (\n _req: Request,\n res: Response<DeleteProjectResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, project, session, roles } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!session) {\n ErrorHandler.handleGenericErrorResponse(res, 'SESSION_NOT_DEFINED');\n return;\n }\n\n if (!hasPermission(roles, 'project:admin')()) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n try {\n const projectToDelete = await projectService.getProjectById(project.id);\n\n if (String(projectToDelete.organizationId) !== String(organization.id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'PROJECT_NOT_IN_ORGANIZATION'\n );\n return;\n }\n\n const deletedProject = await projectService.deleteProjectById(project.id);\n\n if (!deletedProject) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED', {\n projectId: project.id,\n });\n\n return;\n }\n\n logger.info(`Project deleted: ${String(deletedProject.id)}`);\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project deleted successfully',\n fr: 'Projet supprimé avec succès',\n es: 'Proyecto eliminado con éxito',\n }),\n description: t({\n en: 'Your project has been deleted successfully',\n fr: 'Votre projet a été supprimé avec succès',\n es: 'Su proyecto ha sido eliminado con éxito',\n }),\n data: mapProjectToAPI(deletedProject),\n });\n\n await SessionModel.updateOne(\n { _id: session.id },\n { $set: { activeProjectId: null } }\n );\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type SelectProjectParam = { projectId: string | Types.ObjectId };\nexport type SelectProjectResult = ResponseData<ProjectAPI>;\n\n/**\n * Select a project.\n */\nexport const selectProject = async (\n req: Request<SelectProjectParam>,\n res: Response<SelectProjectResult>,\n _next: NextFunction\n) => {\n const { projectId } = req.params;\n const { session, roles } = res.locals;\n\n if (!projectId) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_ID_NOT_FOUND');\n return;\n }\n\n if (!session) {\n ErrorHandler.handleGenericErrorResponse(res, 'SESSION_NOT_DEFINED');\n return;\n }\n\n try {\n const project = await projectService.getProjectById(projectId);\n\n await SessionModel.updateOne(\n { _id: session.id },\n { $set: { activeProjectId: String(projectId) } }\n );\n\n const responseData = formatResponse<ProjectAPI>({\n message: t({\n en: 'Project selected successfully',\n fr: 'Projet sélectionné avec succès',\n es: 'Proyecto seleccionado con éxito',\n }),\n description: t({\n en: 'Your project has been selected successfully',\n fr: 'Votre projet a été sélectionné avec succès',\n es: 'Su proyecto ha sido seleccionado con éxito',\n }),\n data: mapProjectToAPI(project),\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UnselectProjectResult = ResponseData<null>;\n\n/**\n * Unselect a project.\n */\nexport const unselectProject = async (\n _req: Request,\n res: Response<UnselectProjectResult>,\n _next: NextFunction\n) => {\n const { session } = res.locals;\n\n if (!session) {\n ErrorHandler.handleGenericErrorResponse(res, 'SESSION_NOT_DEFINED');\n return;\n }\n\n try {\n await SessionModel.updateOne(\n { _id: session.id },\n { $set: { activeProjectId: null } }\n );\n\n const responseData = formatResponse<null>({\n message: t({\n en: 'Project unselected successfully',\n fr: 'Projet désélectionné avec succès',\n es: 'Proyecto deseleccionado con éxito',\n }),\n description: t({\n en: 'Your project has been unselected successfully',\n fr: 'Votre projet a été désélectionné avec succès',\n es: 'Su proyecto ha sido deseleccionado con éxito',\n }),\n data: null,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":["user"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { sendEmail } from "./../services/email.service.mjs";
|
|
1
2
|
import * as projectAccessKeyService from "./../services/projectAccessKey.service.mjs";
|
|
2
3
|
import { ErrorHandler } from "./../utils/errors/index.mjs";
|
|
4
|
+
import { hasPermission } from "./../utils/permissions.mjs";
|
|
3
5
|
import { formatResponse } from "./../utils/responseData.mjs";
|
|
4
6
|
import { t } from "express-intlayer";
|
|
5
7
|
const addNewAccessKey = async (req, res, _next) => {
|
|
6
|
-
const { user, project,
|
|
8
|
+
const { user, project, roles } = res.locals;
|
|
7
9
|
if (!project) {
|
|
8
10
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
9
11
|
return;
|
|
@@ -12,29 +14,15 @@ const addNewAccessKey = async (req, res, _next) => {
|
|
|
12
14
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
15
|
-
if (!
|
|
16
|
-
ErrorHandler.handleGenericErrorResponse(
|
|
17
|
-
res,
|
|
18
|
-
"ORGANIZATION_RIGHTS_NOT_READ"
|
|
19
|
-
);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (!projectRights) {
|
|
23
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_RIGHTS_NOT_READ");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
if (!dictionaryRights) {
|
|
27
|
-
ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_RIGHTS_NOT_READ");
|
|
17
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
18
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
28
19
|
return;
|
|
29
20
|
}
|
|
30
21
|
try {
|
|
31
22
|
const newAccessKey = await projectAccessKeyService.addNewAccessKey(
|
|
32
23
|
req.body,
|
|
33
|
-
project.
|
|
34
|
-
user
|
|
35
|
-
organizationRights,
|
|
36
|
-
projectRights,
|
|
37
|
-
dictionaryRights
|
|
24
|
+
project.id,
|
|
25
|
+
user
|
|
38
26
|
);
|
|
39
27
|
const responseData = formatResponse({
|
|
40
28
|
message: t({
|
|
@@ -50,6 +38,16 @@ const addNewAccessKey = async (req, res, _next) => {
|
|
|
50
38
|
data: newAccessKey
|
|
51
39
|
});
|
|
52
40
|
res.json(responseData);
|
|
41
|
+
sendEmail({
|
|
42
|
+
type: "oAuthTokenCreated",
|
|
43
|
+
to: user.email,
|
|
44
|
+
username: user.name,
|
|
45
|
+
applicationName: newAccessKey.clientId,
|
|
46
|
+
scopes: newAccessKey.grants,
|
|
47
|
+
tokenDetailsUrl: `${process.env.CLIENT_URL}/oauth2/token`,
|
|
48
|
+
securityLogUrl: `${process.env.CLIENT_URL}/security-log`,
|
|
49
|
+
supportUrl: `${process.env.CLIENT_URL}/support`
|
|
50
|
+
});
|
|
53
51
|
return;
|
|
54
52
|
} catch (error) {
|
|
55
53
|
ErrorHandler.handleAppErrorResponse(res, error);
|
|
@@ -57,7 +55,7 @@ const addNewAccessKey = async (req, res, _next) => {
|
|
|
57
55
|
}
|
|
58
56
|
};
|
|
59
57
|
const deleteAccessKey = async (req, res, _next) => {
|
|
60
|
-
const { user, project } = res.locals;
|
|
58
|
+
const { user, project, roles } = res.locals;
|
|
61
59
|
const { clientId } = req.body;
|
|
62
60
|
if (!project) {
|
|
63
61
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
@@ -71,11 +69,15 @@ const deleteAccessKey = async (req, res, _next) => {
|
|
|
71
69
|
ErrorHandler.handleGenericErrorResponse(res, "CLIENT_ID_NOT_FOUND");
|
|
72
70
|
return;
|
|
73
71
|
}
|
|
72
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
73
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
74
76
|
try {
|
|
75
77
|
const deletedAccessKey = await projectAccessKeyService.deleteAccessKey(
|
|
76
78
|
clientId,
|
|
77
79
|
project,
|
|
78
|
-
user.
|
|
80
|
+
user.id
|
|
79
81
|
);
|
|
80
82
|
if (!deletedAccessKey) {
|
|
81
83
|
ErrorHandler.handleGenericErrorResponse(res, "ACCESS_KEY_NOT_FOUND", {
|
|
@@ -104,7 +106,7 @@ const deleteAccessKey = async (req, res, _next) => {
|
|
|
104
106
|
}
|
|
105
107
|
};
|
|
106
108
|
const refreshAccessKey = async (req, res, _next) => {
|
|
107
|
-
const { user, project } = res.locals;
|
|
109
|
+
const { user, project, roles } = res.locals;
|
|
108
110
|
const { clientId } = req.body;
|
|
109
111
|
if (!project) {
|
|
110
112
|
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
@@ -115,11 +117,15 @@ const refreshAccessKey = async (req, res, _next) => {
|
|
|
115
117
|
if (!clientId) {
|
|
116
118
|
ErrorHandler.handleGenericErrorResponse(res, "CLIENT_ID_NOT_FOUND");
|
|
117
119
|
}
|
|
120
|
+
if (!hasPermission(roles, "project:write")()) {
|
|
121
|
+
ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
118
124
|
try {
|
|
119
125
|
const newAccessKey = await projectAccessKeyService.refreshAccessKey(
|
|
120
126
|
clientId,
|
|
121
|
-
project.
|
|
122
|
-
user.
|
|
127
|
+
project.id,
|
|
128
|
+
user.id
|
|
123
129
|
);
|
|
124
130
|
const responseData = formatResponse({
|
|
125
131
|
message: t({
|