mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 15:53:02 +10:00
feat: add more api logs (#1870)
Adds more detailed API logging using Pino
This commit is contained in:
@ -127,4 +127,6 @@ E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
|
|||||||
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
|
||||||
|
|
||||||
# [[LOGGER]]
|
# [[LOGGER]]
|
||||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=
|
# OPTIONAL: The file to save the logger output to. Will disable stdout if provided.
|
||||||
|
NEXT_PRIVATE_LOGGER_FILE_PATH=
|
||||||
|
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -50,3 +50,6 @@ yarn-error.log*
|
|||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# logs
|
||||||
|
logs.json
|
||||||
137
package-lock.json
generated
137
package-lock.json
generated
@ -3073,36 +3073,6 @@
|
|||||||
"integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==",
|
"integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@honeybadger-io/core": {
|
|
||||||
"version": "6.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/core/-/core-6.7.0.tgz",
|
|
||||||
"integrity": "sha512-bEXRe2UVbfr9q3434/2eO3AHguUT0froYEqrHfTPphR4Aw6+AlFac0YE8elqDZqUSgRQ6m1OXqxmq/HOF+W6LQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"json-nd": "^1.0.0",
|
|
||||||
"stacktrace-parser": "^0.1.10"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@honeybadger-io/js": {
|
|
||||||
"version": "6.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@honeybadger-io/js/-/js-6.11.0.tgz",
|
|
||||||
"integrity": "sha512-nSibKUr9ccrs6Jb3Ql7uO/4MdEEv3ONGP1CrD0w3zSMHUvQKHe43NPYfESA7btxjrf9PVeV+m6ETP/193BSILg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@honeybadger-io/core": "^6.7.0",
|
|
||||||
"@types/aws-lambda": "^8.10.89",
|
|
||||||
"@types/express": "^4.17.13"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"honeybadger-checkins-sync": "scripts/check-ins-sync-bin.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@hono/node-server": {
|
"node_modules/@hono/node-server": {
|
||||||
"version": "1.14.2",
|
"version": "1.14.2",
|
||||||
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.14.2.tgz",
|
||||||
@ -11715,16 +11685,6 @@
|
|||||||
"@babel/types": "^7.20.7"
|
"@babel/types": "^7.20.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/body-parser": {
|
|
||||||
"version": "1.19.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
|
||||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/connect": "*",
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/bunyan": {
|
"node_modules/@types/bunyan": {
|
||||||
"version": "1.8.11",
|
"version": "1.8.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz",
|
||||||
@ -11845,30 +11805,6 @@
|
|||||||
"@types/estree": "*"
|
"@types/estree": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/express": {
|
|
||||||
"version": "4.17.22",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.22.tgz",
|
|
||||||
"integrity": "sha512-eZUmSnhRX9YRSkplpz0N+k6NljUUn5l3EWZIKZvYzhvMphEuNiyyy1viH/ejgt66JWgALwC/gtSUAeQKtSwW/w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/body-parser": "*",
|
|
||||||
"@types/express-serve-static-core": "^4.17.33",
|
|
||||||
"@types/qs": "*",
|
|
||||||
"@types/serve-static": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/express-serve-static-core": {
|
|
||||||
"version": "4.19.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
|
|
||||||
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/qs": "*",
|
|
||||||
"@types/range-parser": "*",
|
|
||||||
"@types/send": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/formidable": {
|
"node_modules/@types/formidable": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-2.0.6.tgz",
|
||||||
@ -11898,12 +11834,6 @@
|
|||||||
"hoist-non-react-statics": "^3.3.0"
|
"hoist-non-react-statics": "^3.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/http-errors": {
|
|
||||||
"version": "2.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
|
||||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||||
@ -11977,12 +11907,6 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/mime": {
|
|
||||||
"version": "1.3.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
|
||||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/minimist": {
|
"node_modules/@types/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
|
||||||
@ -12070,12 +11994,6 @@
|
|||||||
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/qs": {
|
|
||||||
"version": "6.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
|
|
||||||
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/ramda": {
|
"node_modules/@types/ramda": {
|
||||||
"version": "0.30.2",
|
"version": "0.30.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.2.tgz",
|
||||||
@ -12085,12 +12003,6 @@
|
|||||||
"types-ramda": "^0.30.1"
|
"types-ramda": "^0.30.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/range-parser": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
|
||||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.3.5",
|
"version": "18.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz",
|
||||||
@ -12124,27 +12036,6 @@
|
|||||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/send": {
|
|
||||||
"version": "0.17.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
|
||||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/mime": "^1",
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/serve-static": {
|
|
||||||
"version": "1.15.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
|
|
||||||
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/http-errors": "*",
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/send": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/shimmer": {
|
"node_modules/@types/shimmer": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz",
|
||||||
@ -21899,12 +21790,6 @@
|
|||||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/json-nd": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-nd/-/json-nd-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-8TIp0HZAY0VVrwRQJJPb4+nOTSPoOWZeEKBTLizUfQO4oym5Fc/MKqN8vEbLCxcyxDf2vwNxOQ1q84O49GWPyQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/json-parse-even-better-errors": {
|
"node_modules/json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
@ -31491,27 +31376,6 @@
|
|||||||
"integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
|
"integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/stacktrace-parser": {
|
|
||||||
"version": "0.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz",
|
|
||||||
"integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"type-fest": "^0.7.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/stacktrace-parser/node_modules/type-fest": {
|
|
||||||
"version": "0.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
|
|
||||||
"integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
|
|
||||||
"license": "(MIT OR CC0-1.0)",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
@ -36180,7 +36044,6 @@
|
|||||||
"@documenso/email": "*",
|
"@documenso/email": "*",
|
||||||
"@documenso/prisma": "*",
|
"@documenso/prisma": "*",
|
||||||
"@documenso/signing": "*",
|
"@documenso/signing": "*",
|
||||||
"@honeybadger-io/js": "^6.10.1",
|
|
||||||
"@lingui/core": "^5.2.0",
|
"@lingui/core": "^5.2.0",
|
||||||
"@lingui/macro": "^5.2.0",
|
"@lingui/macro": "^5.2.0",
|
||||||
"@lingui/react": "^5.2.0",
|
"@lingui/react": "^5.2.0",
|
||||||
|
|||||||
@ -77,9 +77,15 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getDocument: authenticatedMiddleware(async (args, user, team) => {
|
getDocument: authenticatedMiddleware(async (args, user, team, { logger }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
@ -139,10 +145,16 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
downloadSignedDocument: authenticatedMiddleware(async (args, user, team) => {
|
downloadSignedDocument: authenticatedMiddleware(async (args, user, team, { logger }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
const { downloadOriginalDocument } = args.query;
|
const { downloadOriginalDocument } = args.query;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.NEXT_PUBLIC_UPLOAD_TRANSPORT !== 's3') {
|
if (process.env.NEXT_PUBLIC_UPLOAD_TRANSPORT !== 's3') {
|
||||||
return {
|
return {
|
||||||
@ -204,9 +216,15 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteDocument: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
deleteDocument: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
@ -382,9 +400,15 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTemplate: authenticatedMiddleware(async (args, user, team) => {
|
deleteTemplate: authenticatedMiddleware(async (args, user, team, { logger }) => {
|
||||||
const { id: templateId } = args.params;
|
const { id: templateId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const deletedTemplate = await deleteTemplate({
|
const deletedTemplate = await deleteTemplate({
|
||||||
id: Number(templateId),
|
id: Number(templateId),
|
||||||
@ -406,9 +430,15 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTemplate: authenticatedMiddleware(async (args, user, team) => {
|
getTemplate: authenticatedMiddleware(async (args, user, team, { logger }) => {
|
||||||
const { id: templateId } = args.params;
|
const { id: templateId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const template = await getTemplateById({
|
const template = await getTemplateById({
|
||||||
id: Number(templateId),
|
id: Number(templateId),
|
||||||
@ -463,202 +493,224 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createDocumentFromTemplate: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
createDocumentFromTemplate: authenticatedMiddleware(
|
||||||
const { body, params } = args;
|
async (args, user, team, { logger, metadata }) => {
|
||||||
|
const { body, params } = args;
|
||||||
|
|
||||||
const { remaining } = await getServerLimits({ userId: user.id, teamId: team?.id });
|
logger.info({
|
||||||
|
input: {
|
||||||
if (remaining.documents <= 0) {
|
templateId: params.templateId,
|
||||||
return {
|
|
||||||
status: 400,
|
|
||||||
body: {
|
|
||||||
message: 'You have reached the maximum number of documents allowed for this month',
|
|
||||||
},
|
},
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const templateId = Number(params.templateId);
|
|
||||||
|
|
||||||
const fileName = body.title.endsWith('.pdf') ? body.title : `${body.title}.pdf`;
|
|
||||||
|
|
||||||
const document = await createDocumentFromTemplateLegacy({
|
|
||||||
templateId,
|
|
||||||
userId: user.id,
|
|
||||||
teamId: team?.id,
|
|
||||||
recipients: body.recipients,
|
|
||||||
});
|
|
||||||
|
|
||||||
let documentDataId = document.documentDataId;
|
|
||||||
|
|
||||||
if (body.formValues) {
|
|
||||||
const pdf = await getFileServerSide(document.documentData);
|
|
||||||
|
|
||||||
const prefilled = await insertFormValuesInPdf({
|
|
||||||
pdf: Buffer.from(pdf),
|
|
||||||
formValues: body.formValues,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const newDocumentData = await putPdfFileServerSide({
|
const { remaining } = await getServerLimits({ userId: user.id, teamId: team?.id });
|
||||||
name: fileName,
|
|
||||||
type: 'application/pdf',
|
|
||||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
|
||||||
});
|
|
||||||
|
|
||||||
documentDataId = newDocumentData.id;
|
if (remaining.documents <= 0) {
|
||||||
}
|
return {
|
||||||
|
status: 400,
|
||||||
await updateDocument({
|
body: {
|
||||||
documentId: document.id,
|
message: 'You have reached the maximum number of documents allowed for this month',
|
||||||
userId: user.id,
|
|
||||||
teamId: team?.id,
|
|
||||||
data: {
|
|
||||||
title: fileName,
|
|
||||||
externalId: body.externalId || null,
|
|
||||||
formValues: body.formValues,
|
|
||||||
documentData: {
|
|
||||||
connect: {
|
|
||||||
id: documentDataId,
|
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
},
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (body.meta) {
|
const templateId = Number(params.templateId);
|
||||||
await upsertDocumentMeta({
|
|
||||||
documentId: document.id,
|
|
||||||
userId: user.id,
|
|
||||||
teamId: team?.id,
|
|
||||||
...body.meta,
|
|
||||||
requestMetadata: metadata,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body.authOptions) {
|
const fileName = body.title.endsWith('.pdf') ? body.title : `${body.title}.pdf`;
|
||||||
await updateDocumentSettings({
|
|
||||||
documentId: document.id,
|
|
||||||
userId: user.id,
|
|
||||||
teamId: team?.id,
|
|
||||||
data: body.authOptions,
|
|
||||||
requestMetadata: metadata,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
const document = await createDocumentFromTemplateLegacy({
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
documentId: document.id,
|
|
||||||
recipients: document.recipients.map((recipient) => ({
|
|
||||||
recipientId: recipient.id,
|
|
||||||
name: recipient.name,
|
|
||||||
email: recipient.email,
|
|
||||||
token: recipient.token,
|
|
||||||
role: recipient.role,
|
|
||||||
signingOrder: recipient.signingOrder,
|
|
||||||
|
|
||||||
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
generateDocumentFromTemplate: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
|
||||||
const { body, params } = args;
|
|
||||||
|
|
||||||
const { remaining } = await getServerLimits({ userId: user.id, teamId: team?.id });
|
|
||||||
|
|
||||||
if (remaining.documents <= 0) {
|
|
||||||
return {
|
|
||||||
status: 400,
|
|
||||||
body: {
|
|
||||||
message: 'You have reached the maximum number of documents allowed for this month',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const templateId = Number(params.templateId);
|
|
||||||
|
|
||||||
let document: Awaited<ReturnType<typeof createDocumentFromTemplate>> | null = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
document = await createDocumentFromTemplate({
|
|
||||||
templateId,
|
templateId,
|
||||||
externalId: body.externalId || null,
|
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: team?.id,
|
teamId: team?.id,
|
||||||
recipients: body.recipients,
|
recipients: body.recipients,
|
||||||
prefillFields: body.prefillFields,
|
|
||||||
override: {
|
|
||||||
title: body.title,
|
|
||||||
...body.meta,
|
|
||||||
},
|
|
||||||
requestMetadata: metadata,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
return AppError.toRestAPIError(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body.formValues) {
|
|
||||||
const fileName = document.title.endsWith('.pdf') ? document.title : `${document.title}.pdf`;
|
|
||||||
|
|
||||||
const pdf = await getFileServerSide(document.documentData);
|
|
||||||
|
|
||||||
const prefilled = await insertFormValuesInPdf({
|
|
||||||
pdf: Buffer.from(pdf),
|
|
||||||
formValues: body.formValues,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const newDocumentData = await putPdfFileServerSide({
|
let documentDataId = document.documentDataId;
|
||||||
name: fileName,
|
|
||||||
type: 'application/pdf',
|
if (body.formValues) {
|
||||||
arrayBuffer: async () => Promise.resolve(prefilled),
|
const pdf = await getFileServerSide(document.documentData);
|
||||||
});
|
|
||||||
|
const prefilled = await insertFormValuesInPdf({
|
||||||
|
pdf: Buffer.from(pdf),
|
||||||
|
formValues: body.formValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDocumentData = await putPdfFileServerSide({
|
||||||
|
name: fileName,
|
||||||
|
type: 'application/pdf',
|
||||||
|
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||||
|
});
|
||||||
|
|
||||||
|
documentDataId = newDocumentData.id;
|
||||||
|
}
|
||||||
|
|
||||||
await updateDocument({
|
await updateDocument({
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: team?.id,
|
teamId: team?.id,
|
||||||
data: {
|
data: {
|
||||||
|
title: fileName,
|
||||||
|
externalId: body.externalId || null,
|
||||||
formValues: body.formValues,
|
formValues: body.formValues,
|
||||||
documentData: {
|
documentData: {
|
||||||
connect: {
|
connect: {
|
||||||
id: newDocumentData.id,
|
id: documentDataId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (body.authOptions) {
|
if (body.meta) {
|
||||||
await updateDocumentSettings({
|
await upsertDocumentMeta({
|
||||||
documentId: document.id,
|
documentId: document.id,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId: team?.id,
|
teamId: team?.id,
|
||||||
data: body.authOptions,
|
...body.meta,
|
||||||
requestMetadata: metadata,
|
requestMetadata: metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body.authOptions) {
|
||||||
|
await updateDocumentSettings({
|
||||||
|
documentId: document.id,
|
||||||
|
userId: user.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
data: body.authOptions,
|
||||||
|
requestMetadata: metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
documentId: document.id,
|
||||||
|
recipients: document.recipients.map((recipient) => ({
|
||||||
|
recipientId: recipient.id,
|
||||||
|
name: recipient.name,
|
||||||
|
email: recipient.email,
|
||||||
|
token: recipient.token,
|
||||||
|
role: recipient.role,
|
||||||
|
signingOrder: recipient.signingOrder,
|
||||||
|
|
||||||
|
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
generateDocumentFromTemplate: authenticatedMiddleware(
|
||||||
|
async (args, user, team, { logger, metadata }) => {
|
||||||
|
const { body, params } = args;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
templateId: params.templateId,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
const { remaining } = await getServerLimits({ userId: user.id, teamId: team?.id });
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
documentId: document.id,
|
|
||||||
recipients: document.recipients.map((recipient) => ({
|
|
||||||
recipientId: recipient.id,
|
|
||||||
name: recipient.name,
|
|
||||||
email: recipient.email,
|
|
||||||
token: recipient.token,
|
|
||||||
role: recipient.role,
|
|
||||||
signingOrder: recipient.signingOrder,
|
|
||||||
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
sendDocument: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
if (remaining.documents <= 0) {
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
body: {
|
||||||
|
message: 'You have reached the maximum number of documents allowed for this month',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const templateId = Number(params.templateId);
|
||||||
|
|
||||||
|
let document: Awaited<ReturnType<typeof createDocumentFromTemplate>> | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
document = await createDocumentFromTemplate({
|
||||||
|
templateId,
|
||||||
|
externalId: body.externalId || null,
|
||||||
|
userId: user.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
recipients: body.recipients,
|
||||||
|
prefillFields: body.prefillFields,
|
||||||
|
override: {
|
||||||
|
title: body.title,
|
||||||
|
...body.meta,
|
||||||
|
},
|
||||||
|
requestMetadata: metadata,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
return AppError.toRestAPIError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body.formValues) {
|
||||||
|
const fileName = document.title.endsWith('.pdf') ? document.title : `${document.title}.pdf`;
|
||||||
|
|
||||||
|
const pdf = await getFileServerSide(document.documentData);
|
||||||
|
|
||||||
|
const prefilled = await insertFormValuesInPdf({
|
||||||
|
pdf: Buffer.from(pdf),
|
||||||
|
formValues: body.formValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDocumentData = await putPdfFileServerSide({
|
||||||
|
name: fileName,
|
||||||
|
type: 'application/pdf',
|
||||||
|
arrayBuffer: async () => Promise.resolve(prefilled),
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateDocument({
|
||||||
|
documentId: document.id,
|
||||||
|
userId: user.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
data: {
|
||||||
|
formValues: body.formValues,
|
||||||
|
documentData: {
|
||||||
|
connect: {
|
||||||
|
id: newDocumentData.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body.authOptions) {
|
||||||
|
await updateDocumentSettings({
|
||||||
|
documentId: document.id,
|
||||||
|
userId: user.id,
|
||||||
|
teamId: team?.id,
|
||||||
|
data: body.authOptions,
|
||||||
|
requestMetadata: metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
documentId: document.id,
|
||||||
|
recipients: document.recipients.map((recipient) => ({
|
||||||
|
recipientId: recipient.id,
|
||||||
|
name: recipient.name,
|
||||||
|
email: recipient.email,
|
||||||
|
token: recipient.token,
|
||||||
|
role: recipient.role,
|
||||||
|
signingOrder: recipient.signingOrder,
|
||||||
|
signingUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/sign/${recipient.token}`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
sendDocument: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
const { sendEmail, sendCompletionEmails } = args.body;
|
const { sendEmail, sendCompletionEmails } = args.body;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
@ -730,10 +782,16 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
resendDocument: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
resendDocument: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
const { recipients } = args.body;
|
const { recipients } = args.body;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await resendDocument({
|
await resendDocument({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -759,10 +817,16 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createRecipient: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
createRecipient: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
const { name, email, role, authOptions, signingOrder } = args.body;
|
const { name, email, role, authOptions, signingOrder } = args.body;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -850,10 +914,17 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateRecipient: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
updateRecipient: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId, recipientId } = args.params;
|
const { id: documentId, recipientId } = args.params;
|
||||||
const { name, email, role, authOptions, signingOrder } = args.body;
|
const { name, email, role, authOptions, signingOrder } = args.body;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -916,9 +987,16 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteRecipient: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
deleteRecipient: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId, recipientId } = args.params;
|
const { id: documentId, recipientId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -970,8 +1048,15 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createField: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
createField: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId } = args.params;
|
const { id: documentId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const fields = Array.isArray(args.body) ? args.body : [args.body];
|
const fields = Array.isArray(args.body) ? args.body : [args.body];
|
||||||
|
|
||||||
const document = await prisma.document.findFirst({
|
const document = await prisma.document.findFirst({
|
||||||
@ -1131,11 +1216,18 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateField: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
updateField: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId, fieldId } = args.params;
|
const { id: documentId, fieldId } = args.params;
|
||||||
const { recipientId, type, pageNumber, pageWidth, pageHeight, pageX, pageY, fieldMeta } =
|
const { recipientId, type, pageNumber, pageWidth, pageHeight, pageX, pageY, fieldMeta } =
|
||||||
args.body;
|
args.body;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
@ -1222,9 +1314,16 @@ export const ApiContractV1Implementation = tsr.router(ApiContractV1, {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteField: authenticatedMiddleware(async (args, user, team, { metadata }) => {
|
deleteField: authenticatedMiddleware(async (args, user, team, { logger, metadata }) => {
|
||||||
const { id: documentId, fieldId } = args.params;
|
const { id: documentId, fieldId } = args.params;
|
||||||
|
|
||||||
|
logger.info({
|
||||||
|
input: {
|
||||||
|
id: documentId,
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId: Number(documentId),
|
documentId: Number(documentId),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import type { Team, User } from '@prisma/client';
|
import type { Team, User } from '@prisma/client';
|
||||||
import type { TsRestRequest } from '@ts-rest/serverless';
|
import type { TsRestRequest } from '@ts-rest/serverless';
|
||||||
|
import type { Logger } from 'pino';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
||||||
|
import type { BaseApiLog, RootApiLog } from '@documenso/lib/types/api-logs';
|
||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
|
import { nanoid } from '@documenso/lib/universal/id';
|
||||||
import { logger } from '@documenso/lib/utils/logger';
|
import { logger } from '@documenso/lib/utils/logger';
|
||||||
|
|
||||||
type B = {
|
type B = {
|
||||||
@ -28,10 +31,24 @@ export const authenticatedMiddleware = <
|
|||||||
args: T & { req: TsRestRequest },
|
args: T & { req: TsRestRequest },
|
||||||
user: Pick<User, 'id' | 'email' | 'name' | 'disabled'>,
|
user: Pick<User, 'id' | 'email' | 'name' | 'disabled'>,
|
||||||
team: Team,
|
team: Team,
|
||||||
options: { metadata: ApiRequestMetadata },
|
options: { metadata: ApiRequestMetadata; logger: Logger },
|
||||||
) => Promise<R>,
|
) => Promise<R>,
|
||||||
) => {
|
) => {
|
||||||
return async (args: T, { request }: B) => {
|
return async (args: T, { request }: B) => {
|
||||||
|
const requestMetadata = extractRequestMetadata(request);
|
||||||
|
|
||||||
|
const apiLogger = logger.child({
|
||||||
|
ipAddress: requestMetadata.ipAddress,
|
||||||
|
userAgent: requestMetadata.userAgent,
|
||||||
|
requestId: nanoid(),
|
||||||
|
} satisfies RootApiLog);
|
||||||
|
|
||||||
|
const infoToLog: BaseApiLog = {
|
||||||
|
auth: 'api',
|
||||||
|
source: 'apiV1',
|
||||||
|
path: request.url,
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { authorization } = args.headers;
|
const { authorization } = args.headers;
|
||||||
|
|
||||||
@ -52,8 +69,14 @@ export const authenticatedMiddleware = <
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apiLogger.info({
|
||||||
|
...infoToLog,
|
||||||
|
userId: apiToken.user.id,
|
||||||
|
apiTokenId: apiToken.id,
|
||||||
|
} satisfies BaseApiLog);
|
||||||
|
|
||||||
const metadata: ApiRequestMetadata = {
|
const metadata: ApiRequestMetadata = {
|
||||||
requestMetadata: extractRequestMetadata(request),
|
requestMetadata,
|
||||||
source: 'apiV1',
|
source: 'apiV1',
|
||||||
auth: 'api',
|
auth: 'api',
|
||||||
auditUser: {
|
auditUser: {
|
||||||
@ -63,17 +86,6 @@ export const authenticatedMiddleware = <
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Todo: Get from Hono context instead.
|
|
||||||
logger.info({
|
|
||||||
ipAddress: metadata.requestMetadata.ipAddress,
|
|
||||||
userAgent: metadata.requestMetadata.userAgent,
|
|
||||||
auth: 'api',
|
|
||||||
source: 'apiV1',
|
|
||||||
path: request.url,
|
|
||||||
userId: apiToken.user.id,
|
|
||||||
apiTokenId: apiToken.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return await handler(
|
return await handler(
|
||||||
{
|
{
|
||||||
...args,
|
...args,
|
||||||
@ -81,10 +93,12 @@ export const authenticatedMiddleware = <
|
|||||||
},
|
},
|
||||||
apiToken.user,
|
apiToken.user,
|
||||||
apiToken.team,
|
apiToken.team,
|
||||||
{ metadata },
|
{ metadata, logger: apiLogger },
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log({ err: err });
|
console.log({ err });
|
||||||
|
|
||||||
|
apiLogger.info(infoToLog);
|
||||||
|
|
||||||
let message = 'Unauthorized';
|
let message = 'Unauthorized';
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@
|
|||||||
"@documenso/email": "*",
|
"@documenso/email": "*",
|
||||||
"@documenso/prisma": "*",
|
"@documenso/prisma": "*",
|
||||||
"@documenso/signing": "*",
|
"@documenso/signing": "*",
|
||||||
"@honeybadger-io/js": "^6.10.1",
|
|
||||||
"@lingui/core": "^5.2.0",
|
"@lingui/core": "^5.2.0",
|
||||||
"@lingui/macro": "^5.2.0",
|
"@lingui/macro": "^5.2.0",
|
||||||
"@lingui/react": "^5.2.0",
|
"@lingui/react": "^5.2.0",
|
||||||
|
|||||||
29
packages/lib/types/api-logs.ts
Normal file
29
packages/lib/types/api-logs.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import type { ApiRequestMetadata } from '../universal/extract-request-metadata';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum required fields that the parent API logger must contain.
|
||||||
|
*/
|
||||||
|
export type RootApiLog = {
|
||||||
|
ipAddress?: string;
|
||||||
|
userAgent?: string;
|
||||||
|
requestId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum API log that must be logged at the start of every API request.
|
||||||
|
*/
|
||||||
|
export type BaseApiLog = Partial<RootApiLog> & {
|
||||||
|
path: string;
|
||||||
|
auth: ApiRequestMetadata['auth'];
|
||||||
|
source: ApiRequestMetadata['source'];
|
||||||
|
userId?: number | null;
|
||||||
|
apiTokenId?: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The TRPC API log.
|
||||||
|
*/
|
||||||
|
export type TrpcApiLog = BaseApiLog & {
|
||||||
|
trpcMiddleware: string;
|
||||||
|
unverifiedTeamId?: number | null;
|
||||||
|
};
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { getIpAddress } from './get-ip-address';
|
||||||
|
|
||||||
const ZIpSchema = z.string().ip();
|
const ZIpSchema = z.string().ip();
|
||||||
|
|
||||||
export const ZRequestMetadataSchema = z.object({
|
export const ZRequestMetadataSchema = z.object({
|
||||||
@ -40,11 +42,13 @@ export type ApiRequestMetadata = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const extractRequestMetadata = (req: Request): RequestMetadata => {
|
export const extractRequestMetadata = (req: Request): RequestMetadata => {
|
||||||
const forwardedFor = req.headers.get('x-forwarded-for');
|
let ip: string | undefined = undefined;
|
||||||
const ip = forwardedFor
|
|
||||||
?.split(',')
|
try {
|
||||||
.map((ip) => ip.trim())
|
ip = getIpAddress(req);
|
||||||
.at(0);
|
} catch {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
const parsedIp = ZIpSchema.safeParse(ip);
|
const parsedIp = ZIpSchema.safeParse(ip);
|
||||||
|
|
||||||
|
|||||||
@ -1,112 +0,0 @@
|
|||||||
import Honeybadger from '@honeybadger-io/js';
|
|
||||||
|
|
||||||
import { env } from './env';
|
|
||||||
|
|
||||||
export const buildLogger = () => {
|
|
||||||
if (env('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY')) {
|
|
||||||
return new HoneybadgerLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DefaultLogger();
|
|
||||||
};
|
|
||||||
|
|
||||||
interface LoggerDescriptionOptions {
|
|
||||||
method?: string;
|
|
||||||
path?: string;
|
|
||||||
context?: Record<string, unknown>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of log to be captured.
|
|
||||||
*
|
|
||||||
* Defaults to `info`.
|
|
||||||
*/
|
|
||||||
level?: 'info' | 'error' | 'critical';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic logger implementation intended to be used in the server side for capturing
|
|
||||||
* explicit errors and other logs.
|
|
||||||
*
|
|
||||||
* Not intended to capture the request and responses.
|
|
||||||
*/
|
|
||||||
interface Logger {
|
|
||||||
log(message: string, options?: LoggerDescriptionOptions): void;
|
|
||||||
|
|
||||||
error(error: Error, options?: LoggerDescriptionOptions): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DefaultLogger implements Logger {
|
|
||||||
log(_message: string, _options?: LoggerDescriptionOptions) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
error(_error: Error, _options?: LoggerDescriptionOptions): void {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HoneybadgerLogger implements Logger {
|
|
||||||
constructor() {
|
|
||||||
if (!env('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY')) {
|
|
||||||
throw new Error('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY is not set');
|
|
||||||
}
|
|
||||||
|
|
||||||
Honeybadger.configure({
|
|
||||||
apiKey: env('NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Honeybadger doesn't really have a non-error logging system.
|
|
||||||
*/
|
|
||||||
log(message: string, options?: LoggerDescriptionOptions) {
|
|
||||||
const { context = {}, level = 'info' } = options || {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
Honeybadger.event({
|
|
||||||
message,
|
|
||||||
context: {
|
|
||||||
level,
|
|
||||||
...context,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error(error: Error, options?: LoggerDescriptionOptions): void {
|
|
||||||
const { context = {}, level = 'error', method, path } = options || {};
|
|
||||||
|
|
||||||
// const tags = [`level:${level}`];
|
|
||||||
const tags = [];
|
|
||||||
|
|
||||||
let errorMessage = error.message;
|
|
||||||
|
|
||||||
if (method) {
|
|
||||||
tags.push(`method:${method}`);
|
|
||||||
|
|
||||||
errorMessage = `[${method}]: ${error.message}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
tags.push(`path:${path}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Honeybadger.notify(errorMessage, {
|
|
||||||
context: {
|
|
||||||
level,
|
|
||||||
...context,
|
|
||||||
},
|
|
||||||
tags,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +1,35 @@
|
|||||||
import { pino } from 'pino';
|
import { type TransportTargetOptions, pino } from 'pino';
|
||||||
|
|
||||||
// const transports: TransportTargetOptions[] = [];
|
import { env } from './env';
|
||||||
|
|
||||||
// if (env('NEXT_PRIVATE_LOGGING_DEV')) {
|
const transports: TransportTargetOptions[] = [];
|
||||||
// transports.push({
|
|
||||||
// target: 'pino-pretty',
|
|
||||||
// level: 'info',
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const loggingFilePath = env('NEXT_PRIVATE_LOGGING_FILE_PATH');
|
if (env('NODE_ENV') !== 'production' && !env('INTERNAL_FORCE_JSON_LOGGER')) {
|
||||||
|
transports.push({
|
||||||
|
target: 'pino-pretty',
|
||||||
|
level: 'info',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// if (loggingFilePath) {
|
const loggingFilePath = env('NEXT_PRIVATE_LOGGER_FILE_PATH');
|
||||||
// transports.push({
|
|
||||||
// target: 'pino/file',
|
if (loggingFilePath) {
|
||||||
// level: 'info',
|
transports.push({
|
||||||
// options: {
|
target: 'pino/file',
|
||||||
// destination: loggingFilePath,
|
level: 'info',
|
||||||
// mkdir: true,
|
options: {
|
||||||
// },
|
destination: loggingFilePath,
|
||||||
// });
|
mkdir: true,
|
||||||
// }
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const logger = pino({
|
export const logger = pino({
|
||||||
level: 'info',
|
level: 'info',
|
||||||
|
transport:
|
||||||
|
transports.length > 0
|
||||||
|
? {
|
||||||
|
targets: transports,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,9 +12,15 @@ import {
|
|||||||
export const createAdminOrganisationRoute = adminProcedure
|
export const createAdminOrganisationRoute = adminProcedure
|
||||||
.input(ZCreateAdminOrganisationRequestSchema)
|
.input(ZCreateAdminOrganisationRequestSchema)
|
||||||
.output(ZCreateAdminOrganisationResponseSchema)
|
.output(ZCreateAdminOrganisationResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { ownerUserId, data } = input;
|
const { ownerUserId, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
ownerUserId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await createOrganisation({
|
const organisation = await createOrganisation({
|
||||||
userId: ownerUserId,
|
userId: ownerUserId,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
|
|||||||
@ -11,9 +11,15 @@ import {
|
|||||||
export const createStripeCustomerRoute = adminProcedure
|
export const createStripeCustomerRoute = adminProcedure
|
||||||
.input(ZCreateStripeCustomerRequestSchema)
|
.input(ZCreateStripeCustomerRequestSchema)
|
||||||
.output(ZCreateStripeCustomerResponseSchema)
|
.output(ZCreateStripeCustomerResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findUnique({
|
const organisation = await prisma.organisation.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: organisationId,
|
id: organisationId,
|
||||||
|
|||||||
@ -9,9 +9,13 @@ import {
|
|||||||
export const createSubscriptionClaimRoute = adminProcedure
|
export const createSubscriptionClaimRoute = adminProcedure
|
||||||
.input(ZCreateSubscriptionClaimRequestSchema)
|
.input(ZCreateSubscriptionClaimRequestSchema)
|
||||||
.output(ZCreateSubscriptionClaimResponseSchema)
|
.output(ZCreateSubscriptionClaimResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { name, teamCount, memberCount, flags } = input;
|
const { name, teamCount, memberCount, flags } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input,
|
||||||
|
});
|
||||||
|
|
||||||
await prisma.subscriptionClaim.create({
|
await prisma.subscriptionClaim.create({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
|
|||||||
@ -10,9 +10,15 @@ import {
|
|||||||
export const deleteSubscriptionClaimRoute = adminProcedure
|
export const deleteSubscriptionClaimRoute = adminProcedure
|
||||||
.input(ZDeleteSubscriptionClaimRequestSchema)
|
.input(ZDeleteSubscriptionClaimRequestSchema)
|
||||||
.output(ZDeleteSubscriptionClaimResponseSchema)
|
.output(ZDeleteSubscriptionClaimResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const existingClaim = await prisma.subscriptionClaim.findFirst({
|
const existingClaim = await prisma.subscriptionClaim.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
|
|||||||
@ -10,9 +10,15 @@ import {
|
|||||||
export const getAdminOrganisationRoute = adminProcedure
|
export const getAdminOrganisationRoute = adminProcedure
|
||||||
.input(ZGetAdminOrganisationRequestSchema)
|
.input(ZGetAdminOrganisationRequestSchema)
|
||||||
.output(ZGetAdminOrganisationResponseSchema)
|
.output(ZGetAdminOrganisationResponseSchema)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getAdminOrganisation({
|
return await getAdminOrganisation({
|
||||||
organisationId,
|
organisationId,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -61,17 +61,30 @@ export const adminRouter = router({
|
|||||||
|
|
||||||
updateUser: adminProcedure
|
updateUser: adminProcedure
|
||||||
.input(ZAdminUpdateProfileMutationSchema)
|
.input(ZAdminUpdateProfileMutationSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, name, email, roles } = input;
|
const { id, name, email, roles } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
roles,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateUser({ id, name, email, roles });
|
return await updateUser({ id, name, email, roles });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateRecipient: adminProcedure
|
updateRecipient: adminProcedure
|
||||||
.input(ZAdminUpdateRecipientMutationSchema)
|
.input(ZAdminUpdateRecipientMutationSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, name, email } = input;
|
const { id, name, email } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateRecipient({ id, name, email });
|
return await updateRecipient({ id, name, email });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -80,6 +93,12 @@ export const adminRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { id, enabled, data } = input;
|
const { id, enabled, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await upsertSiteSetting({
|
return await upsertSiteSetting({
|
||||||
id,
|
id,
|
||||||
enabled,
|
enabled,
|
||||||
@ -90,9 +109,15 @@ export const adminRouter = router({
|
|||||||
|
|
||||||
resealDocument: adminProcedure
|
resealDocument: adminProcedure
|
||||||
.input(ZAdminResealDocumentMutationSchema)
|
.input(ZAdminResealDocumentMutationSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getEntireDocument({ id });
|
const document = await getEntireDocument({ id });
|
||||||
|
|
||||||
const isResealing = isDocumentCompleted(document.status);
|
const isResealing = isDocumentCompleted(document.status);
|
||||||
@ -100,44 +125,75 @@ export const adminRouter = router({
|
|||||||
return await sealDocument({ documentId: id, isResealing });
|
return await sealDocument({ documentId: id, isResealing });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
enableUser: adminProcedure.input(ZAdminEnableUserMutationSchema).mutation(async ({ input }) => {
|
enableUser: adminProcedure
|
||||||
const { id } = input;
|
.input(ZAdminEnableUserMutationSchema)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { id } = input;
|
||||||
|
|
||||||
const user = await getUserById({ id }).catch(() => null);
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
if (!user) {
|
id,
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
},
|
||||||
message: 'User not found',
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return await enableUser({ id });
|
const user = await getUserById({ id }).catch(() => null);
|
||||||
}),
|
|
||||||
|
|
||||||
disableUser: adminProcedure.input(ZAdminDisableUserMutationSchema).mutation(async ({ input }) => {
|
if (!user) {
|
||||||
const { id } = input;
|
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||||
|
message: 'User not found',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const user = await getUserById({ id }).catch(() => null);
|
return await enableUser({ id });
|
||||||
|
}),
|
||||||
|
|
||||||
if (!user) {
|
disableUser: adminProcedure
|
||||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
.input(ZAdminDisableUserMutationSchema)
|
||||||
message: 'User not found',
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return await disableUser({ id });
|
const user = await getUserById({ id }).catch(() => null);
|
||||||
}),
|
|
||||||
|
|
||||||
deleteUser: adminProcedure.input(ZAdminDeleteUserMutationSchema).mutation(async ({ input }) => {
|
if (!user) {
|
||||||
const { id } = input;
|
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||||
|
message: 'User not found',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return await deleteUser({ id });
|
return await disableUser({ id });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
deleteUser: adminProcedure
|
||||||
|
.input(ZAdminDeleteUserMutationSchema)
|
||||||
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return await deleteUser({ id });
|
||||||
|
}),
|
||||||
|
|
||||||
deleteDocument: adminProcedure
|
deleteDocument: adminProcedure
|
||||||
.input(ZAdminDeleteDocumentMutationSchema)
|
.input(ZAdminDeleteDocumentMutationSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { id, reason } = input;
|
const { id, reason } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await sendDeleteEmail({ documentId: id, reason });
|
await sendDeleteEmail({ documentId: id, reason });
|
||||||
|
|
||||||
return await superDeleteDocument({
|
return await superDeleteDocument({
|
||||||
|
|||||||
@ -10,9 +10,15 @@ import {
|
|||||||
export const updateAdminOrganisationRoute = adminProcedure
|
export const updateAdminOrganisationRoute = adminProcedure
|
||||||
.input(ZUpdateAdminOrganisationRequestSchema)
|
.input(ZUpdateAdminOrganisationRequestSchema)
|
||||||
.output(ZUpdateAdminOrganisationResponseSchema)
|
.output(ZUpdateAdminOrganisationResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { organisationId, data } = input;
|
const { organisationId, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findUnique({
|
const organisation = await prisma.organisation.findUnique({
|
||||||
where: {
|
where: {
|
||||||
id: organisationId,
|
id: organisationId,
|
||||||
|
|||||||
@ -12,9 +12,13 @@ import {
|
|||||||
export const updateSubscriptionClaimRoute = adminProcedure
|
export const updateSubscriptionClaimRoute = adminProcedure
|
||||||
.input(ZUpdateSubscriptionClaimRequestSchema)
|
.input(ZUpdateSubscriptionClaimRequestSchema)
|
||||||
.output(ZUpdateSubscriptionClaimResponseSchema)
|
.output(ZUpdateSubscriptionClaimResponseSchema)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, data } = input;
|
const { id, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input,
|
||||||
|
});
|
||||||
|
|
||||||
const existingClaim = await prisma.subscriptionClaim.findUnique({
|
const existingClaim = await prisma.subscriptionClaim.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,6 +15,12 @@ export const apiTokenRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { tokenName, teamId, expirationDate } = input;
|
const { tokenName, teamId, expirationDate } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createApiToken({
|
return await createApiToken({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -28,6 +34,13 @@ export const apiTokenRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, teamId } = input;
|
const { id, teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await deleteTokenById({
|
return await deleteTokenById({
|
||||||
id,
|
id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -66,6 +66,12 @@ export const authRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { passkeyId } = input;
|
const { passkeyId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
passkeyId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deletePasskey({
|
await deletePasskey({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
passkeyId,
|
passkeyId,
|
||||||
@ -91,6 +97,12 @@ export const authRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { passkeyId, name } = input;
|
const { passkeyId, name } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
passkeyId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await updatePasskey({
|
await updatePasskey({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
passkeyId,
|
passkeyId,
|
||||||
|
|||||||
@ -14,6 +14,13 @@ export const createSubscriptionRoute = authenticatedProcedure
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { organisationId, priceId } = input;
|
const { organisationId, priceId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
priceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
if (!IS_BILLING_ENABLED()) {
|
if (!IS_BILLING_ENABLED()) {
|
||||||
|
|||||||
@ -13,6 +13,12 @@ export const getInvoicesRoute = authenticatedProcedure
|
|||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
if (!IS_BILLING_ENABLED()) {
|
if (!IS_BILLING_ENABLED()) {
|
||||||
|
|||||||
@ -11,6 +11,12 @@ export const getSubscriptionRoute = authenticatedProcedure
|
|||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
if (!IS_BILLING_ENABLED()) {
|
if (!IS_BILLING_ENABLED()) {
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export const manageSubscriptionRoute = authenticatedProcedure
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
if (!IS_BILLING_ENABLED()) {
|
if (!IS_BILLING_ENABLED()) {
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import type { SessionUser } from '@documenso/auth/server/lib/session/session';
|
import type { SessionUser } from '@documenso/auth/server/lib/session/session';
|
||||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||||
|
import type { RootApiLog } from '@documenso/lib/types/api-logs';
|
||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
import { extractRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import { alphaid } from '@documenso/lib/universal/id';
|
||||||
|
import { logger } from '@documenso/lib/utils/logger';
|
||||||
// This is a bit nasty. Todo: Extract
|
// This is a bit nasty. Todo: Extract
|
||||||
import type { HonoEnv } from '@documenso/remix/server/router';
|
import type { HonoEnv } from '@documenso/remix/server/router';
|
||||||
|
|
||||||
@ -22,16 +24,23 @@ export const createTrpcContext = async ({
|
|||||||
const { session, user } = await getOptionalSession(c);
|
const { session, user } = await getOptionalSession(c);
|
||||||
|
|
||||||
const req = c.req.raw;
|
const req = c.req.raw;
|
||||||
const logger = c.get('logger');
|
|
||||||
|
const requestMetadata = c.get('context').requestMetadata;
|
||||||
|
|
||||||
const metadata: ApiRequestMetadata = {
|
const metadata: ApiRequestMetadata = {
|
||||||
requestMetadata: extractRequestMetadata(req),
|
requestMetadata,
|
||||||
source: requestSource,
|
source: requestSource,
|
||||||
auth: null,
|
auth: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const rawTeamId = req.headers.get('x-team-id') || undefined;
|
const rawTeamId = req.headers.get('x-team-id') || undefined;
|
||||||
|
|
||||||
|
const trpcLogger = logger.child({
|
||||||
|
ipAddress: requestMetadata.ipAddress,
|
||||||
|
userAgent: requestMetadata.userAgent,
|
||||||
|
requestId: alphaid(),
|
||||||
|
} satisfies RootApiLog);
|
||||||
|
|
||||||
const teamId = z.coerce
|
const teamId = z.coerce
|
||||||
.number()
|
.number()
|
||||||
.optional()
|
.optional()
|
||||||
@ -40,7 +49,7 @@ export const createTrpcContext = async ({
|
|||||||
|
|
||||||
if (!session || !user) {
|
if (!session || !user) {
|
||||||
return {
|
return {
|
||||||
logger,
|
logger: trpcLogger,
|
||||||
session: null,
|
session: null,
|
||||||
user: null,
|
user: null,
|
||||||
teamId,
|
teamId,
|
||||||
@ -50,7 +59,7 @@ export const createTrpcContext = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
logger,
|
logger: trpcLogger,
|
||||||
session,
|
session,
|
||||||
user,
|
user,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -62,6 +62,7 @@ export const documentRouter = router({
|
|||||||
find: findInboxRoute,
|
find: findInboxRoute,
|
||||||
getCount: getInboxCountRoute,
|
getCount: getInboxCountRoute,
|
||||||
},
|
},
|
||||||
|
updateDocument: updateDocumentRoute,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -72,6 +73,12 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getDocumentById({
|
return await getDocumentById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -231,6 +238,13 @@ export const documentRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { documentId, folderId } = input;
|
const { documentId, folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getDocumentWithDetailsById({
|
return await getDocumentWithDetailsById({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -332,6 +346,12 @@ export const documentRouter = router({
|
|||||||
const { user, teamId } = ctx;
|
const { user, teamId } = ctx;
|
||||||
const { title, documentDataId, timezone, folderId } = input;
|
const { title, documentDataId, timezone, folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const { remaining } = await getServerLimits({ userId: user.id, teamId });
|
const { remaining } = await getServerLimits({ userId: user.id, teamId });
|
||||||
|
|
||||||
if (remaining.documents <= 0) {
|
if (remaining.documents <= 0) {
|
||||||
@ -353,8 +373,6 @@ export const documentRouter = router({
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
updateDocument: updateDocumentRoute,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
@ -373,6 +391,12 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
await deleteDocument({
|
await deleteDocument({
|
||||||
@ -396,6 +420,13 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, signingOrder } = input;
|
const { documentId, signingOrder } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
signingOrder,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await upsertDocumentMeta({
|
return await upsertDocumentMeta({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -427,6 +458,12 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, meta = {} } = input;
|
const { documentId, meta = {} } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (Object.values(meta).length > 0) {
|
if (Object.values(meta).length > 0) {
|
||||||
await upsertDocumentMeta({
|
await upsertDocumentMeta({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -474,6 +511,13 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipients } = input;
|
const { documentId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
recipients,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await resendDocument({
|
await resendDocument({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -503,6 +547,12 @@ export const documentRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await duplicateDocument({
|
return await duplicateDocument({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -544,6 +594,12 @@ export const documentRouter = router({
|
|||||||
orderByDirection,
|
orderByDirection,
|
||||||
} = input;
|
} = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findDocumentAuditLogs({
|
return await findDocumentAuditLogs({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -565,6 +621,12 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId,
|
documentId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -597,6 +659,12 @@ export const documentRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const document = await getDocumentById({
|
const document = await getDocumentById({
|
||||||
documentId,
|
documentId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
|
|||||||
@ -19,6 +19,12 @@ export const updateDocumentRoute = authenticatedProcedure
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, data, meta = {} } = input;
|
const { documentId, data, meta = {} } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
if (Object.values(meta).length > 0) {
|
if (Object.values(meta).length > 0) {
|
||||||
|
|||||||
@ -16,6 +16,12 @@ export const updateEmbeddingDocumentRoute = procedure
|
|||||||
.input(ZUpdateEmbeddingDocumentRequestSchema)
|
.input(ZUpdateEmbeddingDocumentRequestSchema)
|
||||||
.output(ZUpdateEmbeddingDocumentResponseSchema)
|
.output(ZUpdateEmbeddingDocumentResponseSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId: input.documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,12 @@ export const updateEmbeddingTemplateRoute = procedure
|
|||||||
.input(ZUpdateEmbeddingTemplateRequestSchema)
|
.input(ZUpdateEmbeddingTemplateRequestSchema)
|
||||||
.output(ZUpdateEmbeddingTemplateResponseSchema)
|
.output(ZUpdateEmbeddingTemplateResponseSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId: input.templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { fieldId } = input;
|
const { fieldId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getFieldById({
|
return await getFieldById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -88,6 +94,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, field } = input;
|
const { documentId, field } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const createdFields = await createDocumentFields({
|
const createdFields = await createDocumentFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -118,6 +130,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, fields } = input;
|
const { documentId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createDocumentFields({
|
return await createDocumentFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -146,6 +164,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, field } = input;
|
const { documentId, field } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const updatedFields = await updateDocumentFields({
|
const updatedFields = await updateDocumentFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -176,6 +200,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, fields } = input;
|
const { documentId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateDocumentFields({
|
return await updateDocumentFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -203,6 +233,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { fieldId } = input;
|
const { fieldId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteDocumentField({
|
await deleteDocumentField({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -225,6 +261,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, fields } = input;
|
const { documentId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await setFieldsForDocument({
|
return await setFieldsForDocument({
|
||||||
documentId,
|
documentId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -263,6 +305,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, field } = input;
|
const { templateId, field } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const createdFields = await createTemplateFields({
|
const createdFields = await createTemplateFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -293,6 +341,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { fieldId } = input;
|
const { fieldId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getFieldById({
|
return await getFieldById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -319,6 +373,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, fields } = input;
|
const { templateId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTemplateFields({
|
return await createTemplateFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -346,6 +406,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, field } = input;
|
const { templateId, field } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const updatedFields = await updateTemplateFields({
|
const updatedFields = await updateTemplateFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -375,6 +441,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, fields } = input;
|
const { templateId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateTemplateFields({
|
return await updateTemplateFields({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -401,6 +473,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { fieldId } = input;
|
const { fieldId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteTemplateField({
|
await deleteTemplateField({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -422,6 +500,12 @@ export const fieldRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, fields } = input;
|
const { templateId, fields } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await setFieldsForTemplate({
|
return await setFieldsForTemplate({
|
||||||
templateId,
|
templateId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -448,6 +532,12 @@ export const fieldRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { token, fieldId, value, isBase64, authOptions } = input;
|
const { token, fieldId, value, isBase64, authOptions } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await signFieldWithToken({
|
return await signFieldWithToken({
|
||||||
token,
|
token,
|
||||||
fieldId,
|
fieldId,
|
||||||
@ -467,6 +557,12 @@ export const fieldRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { token, fieldId } = input;
|
const { token, fieldId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
fieldId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await removeSignedFieldWithToken({
|
return await removeSignedFieldWithToken({
|
||||||
token,
|
token,
|
||||||
fieldId,
|
fieldId,
|
||||||
|
|||||||
@ -42,6 +42,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { parentId, type } = input;
|
const { parentId, type } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
parentId,
|
||||||
|
type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const folders = await findFolders({
|
const folders = await findFolders({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -75,6 +82,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { parentId, type } = input;
|
const { parentId, type } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
parentId,
|
||||||
|
type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const folders = await findFolders({
|
const folders = await findFolders({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -107,6 +121,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { name, parentId, type } = input;
|
const { name, parentId, type } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
parentId,
|
||||||
|
type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (parentId) {
|
if (parentId) {
|
||||||
try {
|
try {
|
||||||
await getFolderById({
|
await getFolderById({
|
||||||
@ -146,6 +167,12 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { id, name, visibility } = input;
|
const { id, name, visibility } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const currentFolder = await getFolderById({
|
const currentFolder = await getFolderById({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -177,6 +204,12 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteFolder({
|
await deleteFolder({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -193,6 +226,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { id, parentId } = input;
|
const { id, parentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
parentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const currentFolder = await getFolderById({
|
const currentFolder = await getFolderById({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -238,6 +278,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { documentId, folderId } = input;
|
const { documentId, folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (folderId !== null) {
|
if (folderId !== null) {
|
||||||
try {
|
try {
|
||||||
await getFolderById({
|
await getFolderById({
|
||||||
@ -277,6 +324,13 @@ export const folderRouter = router({
|
|||||||
const { teamId, user } = ctx;
|
const { teamId, user } = ctx;
|
||||||
const { templateId, folderId } = input;
|
const { templateId, folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (folderId !== null) {
|
if (folderId !== null) {
|
||||||
try {
|
try {
|
||||||
await getFolderById({
|
await getFolderById({
|
||||||
@ -310,16 +364,24 @@ export const folderRouter = router({
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
pinFolder: authenticatedProcedure.input(ZPinFolderSchema).mutation(async ({ ctx, input }) => {
|
pinFolder: authenticatedProcedure.input(ZPinFolderSchema).mutation(async ({ ctx, input }) => {
|
||||||
|
const { folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const currentFolder = await getFolderById({
|
const currentFolder = await getFolderById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId: ctx.teamId,
|
teamId: ctx.teamId,
|
||||||
folderId: input.folderId,
|
folderId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await pinFolder({
|
const result = await pinFolder({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId: ctx.teamId,
|
teamId: ctx.teamId,
|
||||||
folderId: input.folderId,
|
folderId,
|
||||||
type: currentFolder.type,
|
type: currentFolder.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -333,16 +395,24 @@ export const folderRouter = router({
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
unpinFolder: authenticatedProcedure.input(ZUnpinFolderSchema).mutation(async ({ ctx, input }) => {
|
unpinFolder: authenticatedProcedure.input(ZUnpinFolderSchema).mutation(async ({ ctx, input }) => {
|
||||||
|
const { folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const currentFolder = await getFolderById({
|
const currentFolder = await getFolderById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId: ctx.teamId,
|
teamId: ctx.teamId,
|
||||||
folderId: input.folderId,
|
folderId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await unpinFolder({
|
const result = await unpinFolder({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId: ctx.teamId,
|
teamId: ctx.teamId,
|
||||||
folderId: input.folderId,
|
folderId,
|
||||||
type: currentFolder.type,
|
type: currentFolder.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,12 @@ export const createOrganisationGroupRoute = authenticatedProcedure
|
|||||||
const { organisationId, organisationRole, name, memberIds } = input;
|
const { organisationId, organisationRole, name, memberIds } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export const createOrganisationMemberInvitesRoute = authenticatedProcedure
|
|||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
const userName = ctx.user.name || '';
|
const userName = ctx.user.name || '';
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await createOrganisationMemberInvites({
|
await createOrganisationMemberInvites({
|
||||||
userId,
|
userId,
|
||||||
userName,
|
userName,
|
||||||
|
|||||||
@ -23,6 +23,12 @@ export const createOrganisationRoute = authenticatedProcedure
|
|||||||
const { name, priceId } = input;
|
const { name, priceId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
priceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Check if user can create a free organiastion.
|
// Check if user can create a free organiastion.
|
||||||
if (IS_BILLING_ENABLED() && !priceId) {
|
if (IS_BILLING_ENABLED() && !priceId) {
|
||||||
const userOrganisations = await prisma.organisation.findMany({
|
const userOrganisations = await prisma.organisation.findMany({
|
||||||
|
|||||||
@ -19,6 +19,13 @@ export const deleteOrganisationGroupRoute = authenticatedProcedure
|
|||||||
const { groupId, organisationId } = input;
|
const { groupId, organisationId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
groupId,
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -19,6 +19,13 @@ export const deleteOrganisationMemberInvitesRoute = authenticatedProcedure
|
|||||||
const { organisationId, invitationIds } = input;
|
const { organisationId, invitationIds } = input;
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
invitationIds,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -13,6 +13,13 @@ export const deleteOrganisationMemberRoute = authenticatedProcedure
|
|||||||
const { organisationId, organisationMemberId } = input;
|
const { organisationId, organisationMemberId } = input;
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
organisationMemberId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteOrganisationMembers({
|
await deleteOrganisationMembers({
|
||||||
userId,
|
userId,
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -21,6 +21,13 @@ export const deleteOrganisationMembersRoute = authenticatedProcedure
|
|||||||
const { organisationId, organisationMemberIds } = input;
|
const { organisationId, organisationMemberIds } = input;
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
organisationMemberIds,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteOrganisationMembers({
|
await deleteOrganisationMembers({
|
||||||
userId,
|
userId,
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -17,6 +17,12 @@ export const deleteOrganisationRoute = authenticatedProcedure
|
|||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -21,6 +21,12 @@ export const findOrganisationGroupsRoute = authenticatedProcedure
|
|||||||
input;
|
input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findOrganisationGroups({
|
return await findOrganisationGroups({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -21,6 +21,12 @@ export const findOrganisationMemberInvitesRoute = authenticatedProcedure
|
|||||||
const { organisationId, query, page, perPage, status } = input;
|
const { organisationId, query, page, perPage, status } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findOrganisationMemberInvites({
|
return await findOrganisationMemberInvites({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export const getOrganisationRoute = authenticatedProcedure
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { organisationReference } = input;
|
const { organisationReference } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationReference,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getOrganisation({
|
return await getOrganisation({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
organisationReference,
|
organisationReference,
|
||||||
|
|||||||
@ -17,9 +17,14 @@ export const leaveOrganisationRoute = authenticatedProcedure
|
|||||||
.output(ZLeaveOrganisationResponseSchema)
|
.output(ZLeaveOrganisationResponseSchema)
|
||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({ organisationId, userId }),
|
where: buildOrganisationWhereQuery({ organisationId, userId }),
|
||||||
include: {
|
include: {
|
||||||
|
|||||||
@ -20,6 +20,13 @@ export const resendOrganisationMemberInviteRoute = authenticatedProcedure
|
|||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
const userName = ctx.user.name || '';
|
const userName = ctx.user.name || '';
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
invitationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await resendOrganisationMemberInvitation({
|
await resendOrganisationMemberInvitation({
|
||||||
userId,
|
userId,
|
||||||
userName,
|
userName,
|
||||||
|
|||||||
@ -25,6 +25,12 @@ export const updateOrganisationGroupRoute = authenticatedProcedure
|
|||||||
const { id, ...data } = input;
|
const { id, ...data } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisationGroup = await prisma.organisationGroup.findFirst({
|
const organisationGroup = await prisma.organisationGroup.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
|
|||||||
@ -24,6 +24,13 @@ export const updateOrganisationMemberRoute = authenticatedProcedure
|
|||||||
const { organisationId, organisationMemberId, data } = input;
|
const { organisationId, organisationMemberId, data } = input;
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
organisationMemberId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const organisation = await prisma.organisation.findFirst({
|
const organisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
organisationId,
|
organisationId,
|
||||||
|
|||||||
@ -16,6 +16,12 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
|
|||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
const { organisationId, data } = input;
|
const { organisationId, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
// Document related settings.
|
// Document related settings.
|
||||||
documentVisibility,
|
documentVisibility,
|
||||||
|
|||||||
@ -15,9 +15,14 @@ export const updateOrganisationRoute = authenticatedProcedure
|
|||||||
.output(ZUpdateOrganisationResponseSchema)
|
.output(ZUpdateOrganisationResponseSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { organisationId, data } = input;
|
const { organisationId, data } = input;
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Check if organisation exists and user has access to it
|
// Check if organisation exists and user has access to it
|
||||||
const existingOrganisation = await prisma.organisation.findFirst({
|
const existingOrganisation = await prisma.organisation.findFirst({
|
||||||
where: buildOrganisationWhereQuery({
|
where: buildOrganisationWhereQuery({
|
||||||
|
|||||||
@ -23,9 +23,15 @@ export const profileRouter = router({
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getUser: adminProcedure.input(ZRetrieveUserByIdQuerySchema).query(async ({ input }) => {
|
getUser: adminProcedure.input(ZRetrieveUserByIdQuerySchema).query(async ({ input, ctx }) => {
|
||||||
const { id } = input;
|
const { id } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getUserById({ id });
|
return await getUserById({ id });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -53,6 +59,13 @@ export const profileRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { bytes, teamId, organisationId } = input;
|
const { bytes, teamId, organisationId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
let target: SetAvatarImageOptions['target'] = {
|
let target: SetAvatarImageOptions['target'] = {
|
||||||
type: 'user',
|
type: 'user',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -62,6 +62,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { recipientId } = input;
|
const { recipientId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getRecipientById({
|
return await getRecipientById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -88,6 +94,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipient } = input;
|
const { documentId, recipient } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const createdRecipients = await createDocumentRecipients({
|
const createdRecipients = await createDocumentRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -118,6 +130,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipients } = input;
|
const { documentId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createDocumentRecipients({
|
return await createDocumentRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -146,6 +164,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipient } = input;
|
const { documentId, recipient } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const updatedRecipients = await updateDocumentRecipients({
|
const updatedRecipients = await updateDocumentRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -176,6 +200,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipients } = input;
|
const { documentId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateDocumentRecipients({
|
return await updateDocumentRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -203,6 +233,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { recipientId } = input;
|
const { recipientId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteDocumentRecipient({
|
await deleteDocumentRecipient({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -223,6 +259,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { documentId, recipients } = input;
|
const { documentId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await setDocumentRecipients({
|
return await setDocumentRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -259,6 +301,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { recipientId } = input;
|
const { recipientId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getRecipientById({
|
return await getRecipientById({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -285,6 +333,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, recipient } = input;
|
const { templateId, recipient } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const createdRecipients = await createTemplateRecipients({
|
const createdRecipients = await createTemplateRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -314,6 +368,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, recipients } = input;
|
const { templateId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTemplateRecipients({
|
return await createTemplateRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -341,6 +401,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, recipient } = input;
|
const { templateId, recipient } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const updatedRecipients = await updateTemplateRecipients({
|
const updatedRecipients = await updateTemplateRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -370,6 +436,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, recipients } = input;
|
const { templateId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateTemplateRecipients({
|
return await updateTemplateRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -396,6 +468,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { recipientId } = input;
|
const { recipientId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteTemplateRecipient({
|
await deleteTemplateRecipient({
|
||||||
recipientId,
|
recipientId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -415,6 +493,12 @@ export const recipientRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, recipients } = input;
|
const { templateId, recipients } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await setTemplateRecipients({
|
return await setTemplateRecipients({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -438,6 +522,12 @@ export const recipientRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { token, documentId, authOptions, nextSigner } = input;
|
const { token, documentId, authOptions, nextSigner } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await completeDocumentWithToken({
|
return await completeDocumentWithToken({
|
||||||
token,
|
token,
|
||||||
documentId,
|
documentId,
|
||||||
@ -456,6 +546,12 @@ export const recipientRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { token, documentId, reason } = input;
|
const { token, documentId, reason } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await rejectDocumentWithToken({
|
return await rejectDocumentWithToken({
|
||||||
token,
|
token,
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export const getDocumentInternalUrlForQRCodeRoute = procedure
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { documentId } = input;
|
const { documentId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!ctx.user) {
|
if (!ctx.user) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,12 @@ export const shareLinkRouter = router({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
const { documentId, token } = input;
|
const { documentId, token } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
documentId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
return await createOrGetShareLink({ documentId, token });
|
return await createOrGetShareLink({ documentId, token });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,13 @@ export const createTeamGroupsRoute = authenticatedProcedure
|
|||||||
const { teamId, groups } = input;
|
const { teamId, groups } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
groups,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const team = await prisma.team.findFirst({
|
const team = await prisma.team.findFirst({
|
||||||
where: buildTeamWhereQuery({
|
where: buildTeamWhereQuery({
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -21,6 +21,13 @@ export const createTeamMembersRoute = authenticatedProcedure
|
|||||||
const { teamId, organisationMembers } = input;
|
const { teamId, organisationMembers } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
organisationMembers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTeamMembers({
|
return await createTeamMembers({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -11,6 +11,12 @@ export const createTeamRoute = authenticatedProcedure
|
|||||||
const { teamName, teamUrl, organisationId, inheritMembers } = input;
|
const { teamName, teamUrl, organisationId, inheritMembers } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTeam({
|
return await createTeam({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamName,
|
teamName,
|
||||||
|
|||||||
@ -19,6 +19,13 @@ export const deleteTeamGroupRoute = authenticatedProcedure
|
|||||||
const { teamGroupId, teamId } = input;
|
const { teamGroupId, teamId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamGroupId,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const team = await prisma.team.findFirst({
|
const team = await prisma.team.findFirst({
|
||||||
where: buildTeamWhereQuery({
|
where: buildTeamWhereQuery({
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -20,6 +20,13 @@ export const deleteTeamMemberRoute = authenticatedProcedure
|
|||||||
const { teamId, memberId } = input;
|
const { teamId, memberId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
memberId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const team = await prisma.team.findFirst({
|
const team = await prisma.team.findFirst({
|
||||||
where: buildTeamWhereQuery({
|
where: buildTeamWhereQuery({
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -11,6 +11,12 @@ export const deleteTeamRoute = authenticatedProcedure
|
|||||||
const { teamId } = input;
|
const { teamId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteTeam({
|
await deleteTeam({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -20,6 +20,13 @@ export const findTeamGroupsRoute = authenticatedProcedure
|
|||||||
const { teamId, types, query, page, perPage, teamGroupId, organisationRoles } = input;
|
const { teamId, types, query, page, perPage, teamGroupId, organisationRoles } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
teamGroupId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findTeamGroups({
|
return await findTeamGroups({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -13,6 +13,12 @@ export const findTeamMembersRoute = authenticatedProcedure
|
|||||||
const { teamId, query, page, perPage } = input;
|
const { teamId, query, page, perPage } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findTeamMembers({
|
return await findTeamMembers({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -11,5 +11,11 @@ export const findTeamsRoute = authenticatedProcedure
|
|||||||
const { organisationId } = input;
|
const { organisationId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
organisationId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return findTeams({ userId: user.id, organisationId });
|
return findTeams({ userId: user.id, organisationId });
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export const getTeamMembersRoute = authenticatedProcedure
|
|||||||
const { teamId } = input;
|
const { teamId } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getTeamMembers({
|
return await getTeamMembers({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
teamId,
|
teamId,
|
||||||
|
|||||||
@ -8,8 +8,16 @@ export const getTeamRoute = authenticatedProcedure
|
|||||||
.input(ZGetTeamRequestSchema)
|
.input(ZGetTeamRequestSchema)
|
||||||
.output(ZGetTeamResponseSchema)
|
.output(ZGetTeamResponseSchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
|
const { teamReference } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamReference,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getTeam({
|
return await getTeam({
|
||||||
teamReference: input.teamReference,
|
teamReference,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -61,6 +61,12 @@ export const teamRouter = router({
|
|||||||
update: authenticatedProcedure
|
update: authenticatedProcedure
|
||||||
.input(ZUpdateTeamEmailMutationSchema)
|
.input(ZUpdateTeamEmailMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId: input.teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateTeamEmail({
|
return await updateTeamEmail({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
...input,
|
||||||
@ -69,39 +75,71 @@ export const teamRouter = router({
|
|||||||
delete: authenticatedProcedure
|
delete: authenticatedProcedure
|
||||||
.input(ZDeleteTeamEmailMutationSchema)
|
.input(ZDeleteTeamEmailMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await deleteTeamEmail({
|
return await deleteTeamEmail({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
userEmail: ctx.user.email,
|
userEmail: ctx.user.email,
|
||||||
...input,
|
teamId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
verification: {
|
verification: {
|
||||||
send: authenticatedProcedure
|
send: authenticatedProcedure
|
||||||
.input(ZCreateTeamEmailVerificationMutationSchema)
|
.input(ZCreateTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { teamId, email, name } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTeamEmailVerification({
|
return await createTeamEmailVerification({
|
||||||
teamId: input.teamId,
|
teamId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
data: {
|
data: {
|
||||||
email: input.email,
|
email,
|
||||||
name: input.name,
|
name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
resend: authenticatedProcedure
|
resend: authenticatedProcedure
|
||||||
.input(ZResendTeamEmailVerificationMutationSchema)
|
.input(ZResendTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await resendTeamEmailVerification({
|
await resendTeamEmailVerification({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
teamId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
delete: authenticatedProcedure
|
delete: authenticatedProcedure
|
||||||
.input(ZDeleteTeamEmailVerificationMutationSchema)
|
.input(ZDeleteTeamEmailVerificationMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
const { teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await deleteTeamEmailVerification({
|
return await deleteTeamEmailVerification({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
...input,
|
teamId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -19,6 +19,15 @@ export const updateTeamGroupRoute = authenticatedProcedure
|
|||||||
const { id, data } = input;
|
const { id, data } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
data: {
|
||||||
|
teamRole: data.teamRole,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const teamGroup = await prisma.teamGroup.findFirst({
|
const teamGroup = await prisma.teamGroup.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
|
|||||||
@ -22,6 +22,13 @@ export const updateTeamMemberRoute = authenticatedProcedure
|
|||||||
const { teamId, memberId, data } = input;
|
const { teamId, memberId, data } = input;
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
memberId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const team = await prisma.team.findFirst({
|
const team = await prisma.team.findFirst({
|
||||||
where: {
|
where: {
|
||||||
AND: [
|
AND: [
|
||||||
|
|||||||
@ -16,6 +16,12 @@ export const updateTeamSettingsRoute = authenticatedProcedure
|
|||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
const { teamId, data } = input;
|
const { teamId, data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
// Document related settings.
|
// Document related settings.
|
||||||
documentVisibility,
|
documentVisibility,
|
||||||
|
|||||||
@ -13,6 +13,12 @@ export const updateTeamRoute = authenticatedProcedure
|
|||||||
|
|
||||||
const { name, url, profileBio, profileEnabled } = data;
|
const { name, url, profileBio, profileEnabled } = data;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (name || url) {
|
if (name || url) {
|
||||||
await updateTeam({
|
await updateTeam({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
|
|||||||
@ -67,6 +67,12 @@ export const templateRouter = router({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
folderId: input.folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await findTemplates({
|
return await findTemplates({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -92,6 +98,12 @@ export const templateRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId } = input;
|
const { templateId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getTemplateById({
|
return await getTemplateById({
|
||||||
id: templateId,
|
id: templateId,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -120,6 +132,12 @@ export const templateRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { title, templateDocumentDataId, folderId } = input;
|
const { title, templateDocumentDataId, folderId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
folderId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createTemplate({
|
return await createTemplate({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -146,9 +164,14 @@ export const templateRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId, data, meta } = input;
|
const { templateId, data, meta } = input;
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await updateTemplate({
|
return await updateTemplate({
|
||||||
userId,
|
userId,
|
||||||
teamId,
|
teamId,
|
||||||
@ -176,6 +199,12 @@ export const templateRouter = router({
|
|||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId } = input;
|
const { templateId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await duplicateTemplate({
|
return await duplicateTemplate({
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -200,9 +229,14 @@ export const templateRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { teamId } = ctx;
|
const { teamId } = ctx;
|
||||||
const { templateId } = input;
|
const { templateId } = input;
|
||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteTemplate({ userId, id: templateId, teamId });
|
await deleteTemplate({ userId, id: templateId, teamId });
|
||||||
|
|
||||||
return ZGenericSuccessResponse;
|
return ZGenericSuccessResponse;
|
||||||
@ -228,6 +262,12 @@ export const templateRouter = router({
|
|||||||
const { templateId, recipients, distributeDocument, customDocumentDataId, prefillFields } =
|
const { templateId, recipients, distributeDocument, customDocumentDataId, prefillFields } =
|
||||||
input;
|
input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const limits = await getServerLimits({ userId: ctx.user.id, teamId });
|
const limits = await getServerLimits({ userId: ctx.user.id, teamId });
|
||||||
|
|
||||||
if (limits.remaining.documents === 0) {
|
if (limits.remaining.documents === 0) {
|
||||||
@ -291,6 +331,12 @@ export const templateRouter = router({
|
|||||||
templateUpdatedAt,
|
templateUpdatedAt,
|
||||||
} = input;
|
} = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
directTemplateToken,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createDocumentFromDirectTemplate({
|
return await createDocumentFromDirectTemplate({
|
||||||
directRecipientName,
|
directRecipientName,
|
||||||
directRecipientEmail,
|
directRecipientEmail,
|
||||||
@ -330,6 +376,13 @@ export const templateRouter = router({
|
|||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
directRecipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
||||||
|
|
||||||
const limits = await getServerLimits({ userId: ctx.user.id, teamId: template.teamId });
|
const limits = await getServerLimits({ userId: ctx.user.id, teamId: template.teamId });
|
||||||
@ -364,6 +417,12 @@ export const templateRouter = router({
|
|||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await deleteTemplateDirectLink({ userId, teamId, templateId });
|
await deleteTemplateDirectLink({ userId, teamId, templateId });
|
||||||
|
|
||||||
return ZGenericSuccessResponse;
|
return ZGenericSuccessResponse;
|
||||||
@ -390,6 +449,12 @@ export const templateRouter = router({
|
|||||||
|
|
||||||
const userId = ctx.user.id;
|
const userId = ctx.user.id;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await toggleTemplateDirectLink({ userId, teamId, templateId, enabled });
|
return await toggleTemplateDirectLink({ userId, teamId, templateId, enabled });
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -402,6 +467,13 @@ export const templateRouter = router({
|
|||||||
const { templateId, teamId, csv, sendImmediately } = input;
|
const { templateId, teamId, csv, sendImmediately } = input;
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
templateId,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (csv.length > 4 * 1024 * 1024) {
|
if (csv.length > 4 * 1024 * 1024) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: 'BAD_REQUEST',
|
code: 'BAD_REQUEST',
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import type { AnyZodObject } from 'zod';
|
|||||||
|
|
||||||
import { AppError, genericErrorCodeToTrpcErrorCodeMap } from '@documenso/lib/errors/app-error';
|
import { AppError, genericErrorCodeToTrpcErrorCodeMap } from '@documenso/lib/errors/app-error';
|
||||||
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
||||||
|
import type { TrpcApiLog } from '@documenso/lib/types/api-logs';
|
||||||
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||||
|
import { alphaid } from '@documenso/lib/universal/id';
|
||||||
import { isAdmin } from '@documenso/lib/utils/is-admin';
|
import { isAdmin } from '@documenso/lib/utils/is-admin';
|
||||||
|
|
||||||
import type { TrpcContext } from './context';
|
import type { TrpcContext } from './context';
|
||||||
@ -66,11 +68,13 @@ const t = initTRPC
|
|||||||
* Middlewares
|
* Middlewares
|
||||||
*/
|
*/
|
||||||
export const authenticatedMiddleware = t.middleware(async ({ ctx, next, path }) => {
|
export const authenticatedMiddleware = t.middleware(async ({ ctx, next, path }) => {
|
||||||
const logger = ctx.logger.child({
|
const infoToLog: TrpcApiLog = {
|
||||||
path,
|
path,
|
||||||
auth: ctx.metadata.auth,
|
auth: ctx.metadata.auth,
|
||||||
source: ctx.metadata.source,
|
source: ctx.metadata.source,
|
||||||
});
|
trpcMiddleware: 'authenticated',
|
||||||
|
unverifiedTeamId: ctx.teamId,
|
||||||
|
};
|
||||||
|
|
||||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||||
|
|
||||||
@ -85,10 +89,11 @@ export const authenticatedMiddleware = t.middleware(async ({ ctx, next, path })
|
|||||||
|
|
||||||
const apiToken = await getApiTokenByToken({ token });
|
const apiToken = await getApiTokenByToken({ token });
|
||||||
|
|
||||||
logger.info({
|
ctx.logger.info({
|
||||||
|
...infoToLog,
|
||||||
userId: apiToken.user.id,
|
userId: apiToken.user.id,
|
||||||
apiTokenId: apiToken.id,
|
apiTokenId: apiToken.id,
|
||||||
});
|
} satisfies TrpcApiLog);
|
||||||
|
|
||||||
return await next({
|
return await next({
|
||||||
ctx: {
|
ctx: {
|
||||||
@ -122,14 +127,21 @@ export const authenticatedMiddleware = t.middleware(async ({ ctx, next, path })
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info({
|
// Recreate the logger with a sub request ID to differentiate between batched requests.
|
||||||
|
const trpcSessionLogger = ctx.logger.child({
|
||||||
|
nonBatchedRequestId: alphaid(),
|
||||||
|
});
|
||||||
|
|
||||||
|
trpcSessionLogger.info({
|
||||||
|
...infoToLog,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
apiTokenId: null,
|
apiTokenId: null,
|
||||||
});
|
} satisfies TrpcApiLog);
|
||||||
|
|
||||||
return await next({
|
return await next({
|
||||||
ctx: {
|
ctx: {
|
||||||
...ctx,
|
...ctx,
|
||||||
|
logger: trpcSessionLogger,
|
||||||
user: ctx.user,
|
user: ctx.user,
|
||||||
session: ctx.session,
|
session: ctx.session,
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -145,10 +157,26 @@ export const authenticatedMiddleware = t.middleware(async ({ ctx, next, path })
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export const maybeAuthenticatedMiddleware = t.middleware(async ({ ctx, next }) => {
|
export const maybeAuthenticatedMiddleware = t.middleware(async ({ ctx, next, path }) => {
|
||||||
|
// Recreate the logger with a sub request ID to differentiate between batched requests.
|
||||||
|
const trpcSessionLogger = ctx.logger.child({
|
||||||
|
nonBatchedRequestId: alphaid(),
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
path,
|
||||||
|
auth: ctx.metadata.auth,
|
||||||
|
source: ctx.metadata.source,
|
||||||
|
userId: ctx.user?.id,
|
||||||
|
apiTokenId: null,
|
||||||
|
trpcMiddleware: 'maybeAuthenticated',
|
||||||
|
unverifiedTeamId: ctx.teamId,
|
||||||
|
} satisfies TrpcApiLog);
|
||||||
|
|
||||||
return await next({
|
return await next({
|
||||||
ctx: {
|
ctx: {
|
||||||
...ctx,
|
...ctx,
|
||||||
|
logger: trpcSessionLogger,
|
||||||
user: ctx.user,
|
user: ctx.user,
|
||||||
session: ctx.session,
|
session: ctx.session,
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -166,7 +194,7 @@ export const maybeAuthenticatedMiddleware = t.middleware(async ({ ctx, next }) =
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export const adminMiddleware = t.middleware(async ({ ctx, next }) => {
|
export const adminMiddleware = t.middleware(async ({ ctx, next, path }) => {
|
||||||
if (!ctx.session || !ctx.user) {
|
if (!ctx.session || !ctx.user) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: 'UNAUTHORIZED',
|
code: 'UNAUTHORIZED',
|
||||||
@ -183,9 +211,24 @@ export const adminMiddleware = t.middleware(async ({ ctx, next }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recreate the logger with a sub request ID to differentiate between batched requests.
|
||||||
|
const trpcSessionLogger = ctx.logger.child({
|
||||||
|
nonBatchedRequestId: alphaid(),
|
||||||
|
});
|
||||||
|
|
||||||
|
trpcSessionLogger.info({
|
||||||
|
path,
|
||||||
|
auth: ctx.metadata.auth,
|
||||||
|
source: ctx.metadata.source,
|
||||||
|
userId: ctx.user.id,
|
||||||
|
apiTokenId: null,
|
||||||
|
trpcMiddleware: 'admin',
|
||||||
|
} satisfies TrpcApiLog);
|
||||||
|
|
||||||
return await next({
|
return await next({
|
||||||
ctx: {
|
ctx: {
|
||||||
...ctx,
|
...ctx,
|
||||||
|
logger: trpcSessionLogger,
|
||||||
user: ctx.user,
|
user: ctx.user,
|
||||||
session: ctx.session,
|
session: ctx.session,
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -201,11 +244,34 @@ export const adminMiddleware = t.middleware(async ({ ctx, next }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const procedureMiddleware = t.middleware(async ({ ctx, next, path }) => {
|
||||||
|
// Recreate the logger with a sub request ID to differentiate between batched requests.
|
||||||
|
const trpcSessionLogger = ctx.logger.child({
|
||||||
|
nonBatchedRequestId: alphaid(),
|
||||||
|
});
|
||||||
|
|
||||||
|
trpcSessionLogger.info({
|
||||||
|
path,
|
||||||
|
auth: ctx.metadata.auth,
|
||||||
|
source: ctx.metadata.source,
|
||||||
|
userId: ctx.user?.id,
|
||||||
|
apiTokenId: null,
|
||||||
|
trpcMiddleware: 'procedure',
|
||||||
|
} satisfies TrpcApiLog);
|
||||||
|
|
||||||
|
return await next({
|
||||||
|
ctx: {
|
||||||
|
...ctx,
|
||||||
|
logger: trpcSessionLogger,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routers and Procedures
|
* Routers and Procedures
|
||||||
*/
|
*/
|
||||||
export const router = t.router;
|
export const router = t.router;
|
||||||
export const procedure = t.procedure;
|
export const procedure = t.procedure.use(procedureMiddleware);
|
||||||
export const authenticatedProcedure = t.procedure.use(authenticatedMiddleware);
|
export const authenticatedProcedure = t.procedure.use(authenticatedMiddleware);
|
||||||
// While this is functionally the same as `procedure`, it's useful for indicating purpose
|
// While this is functionally the same as `procedure`, it's useful for indicating purpose
|
||||||
export const maybeAuthenticatedProcedure = t.procedure.use(maybeAuthenticatedMiddleware);
|
export const maybeAuthenticatedProcedure = t.procedure.use(maybeAuthenticatedMiddleware);
|
||||||
|
|||||||
@ -19,6 +19,12 @@ export const webhookRouter = router({
|
|||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
const { teamId } = input;
|
const { teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getWebhooksByTeamId(teamId, ctx.user.id);
|
return await getWebhooksByTeamId(teamId, ctx.user.id);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -27,6 +33,13 @@ export const webhookRouter = router({
|
|||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
const { id, teamId } = input;
|
const { id, teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await getWebhookById({
|
return await getWebhookById({
|
||||||
id,
|
id,
|
||||||
userId: ctx.user.id,
|
userId: ctx.user.id,
|
||||||
@ -39,6 +52,12 @@ export const webhookRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { enabled, eventTriggers, secret, webhookUrl, teamId } = input;
|
const { enabled, eventTriggers, secret, webhookUrl, teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await createWebhook({
|
return await createWebhook({
|
||||||
enabled,
|
enabled,
|
||||||
secret,
|
secret,
|
||||||
@ -54,6 +73,13 @@ export const webhookRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, teamId } = input;
|
const { id, teamId } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await deleteWebhookById({
|
return await deleteWebhookById({
|
||||||
id,
|
id,
|
||||||
teamId,
|
teamId,
|
||||||
@ -66,6 +92,13 @@ export const webhookRouter = router({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const { id, teamId, ...data } = input;
|
const { id, teamId, ...data } = input;
|
||||||
|
|
||||||
|
ctx.logger.info({
|
||||||
|
input: {
|
||||||
|
id,
|
||||||
|
teamId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return await editWebhook({
|
return await editWebhook({
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import type { ErrorHandlerOptions } from '@trpc/server/unstable-core-do-not-import';
|
import type { ErrorHandlerOptions } from '@trpc/server/unstable-core-do-not-import';
|
||||||
|
|
||||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||||
import { buildLogger } from '@documenso/lib/utils/logger-legacy';
|
import { logger } from '@documenso/lib/utils/logger';
|
||||||
|
|
||||||
const logger = buildLogger();
|
import type { TrpcContext } from '../server/context';
|
||||||
|
|
||||||
// Parameters<NonNullable<Parameters<typeof trpcServer>[0]['onError']>>[0], // :-)
|
// Parameters<NonNullable<Parameters<typeof trpcServer>[0]['onError']>>[0], // :-)
|
||||||
export const handleTrpcRouterError = (
|
export const handleTrpcRouterError = (
|
||||||
{ error, path }: Pick<ErrorHandlerOptions<undefined>, 'error' | 'path'>,
|
{ error, ctx }: Pick<ErrorHandlerOptions<TrpcContext>, 'error' | 'path' | 'ctx'>,
|
||||||
source: 'trpc' | 'apiV1' | 'apiV2',
|
_source: 'trpc' | 'apiV1' | 'apiV2',
|
||||||
) => {
|
) => {
|
||||||
const appError = AppError.parseError(error.cause || error);
|
const appError = AppError.parseError(error.cause || error);
|
||||||
|
|
||||||
@ -23,16 +23,16 @@ export const handleTrpcRouterError = (
|
|||||||
// not an AppError.
|
// not an AppError.
|
||||||
const isLoggableTrpcError = !isAppError && errorCodesToAlertOn.includes(error.code);
|
const isLoggableTrpcError = !isAppError && errorCodesToAlertOn.includes(error.code);
|
||||||
|
|
||||||
if (isLoggableAppError || isLoggableTrpcError) {
|
const errorLogger = (ctx?.logger || logger).child({
|
||||||
console.error(error);
|
status: 'error',
|
||||||
|
appError: AppError.toJSON(appError),
|
||||||
|
});
|
||||||
|
|
||||||
logger.error(error, {
|
// Only fully log the error on certain conditions since some errors are expected.
|
||||||
method: path,
|
if (isLoggableAppError || isLoggableTrpcError) {
|
||||||
context: {
|
errorLogger.error(error);
|
||||||
source,
|
} else {
|
||||||
appError: AppError.toJSON(appError),
|
errorLogger.info('TRPC_ERROR_HANDLER');
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
4
packages/tsconfig/process-env.d.ts
vendored
4
packages/tsconfig/process-env.d.ts
vendored
@ -15,6 +15,8 @@ declare namespace NodeJS {
|
|||||||
NEXT_PRIVATE_ENCRYPTION_KEY: string;
|
NEXT_PRIVATE_ENCRYPTION_KEY: string;
|
||||||
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY: string;
|
NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY: string;
|
||||||
|
|
||||||
|
NEXT_PRIVATE_LOGGER_FILE_PATH?: string;
|
||||||
|
|
||||||
NEXT_PRIVATE_STRIPE_API_KEY: string;
|
NEXT_PRIVATE_STRIPE_API_KEY: string;
|
||||||
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET: string;
|
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET: string;
|
||||||
|
|
||||||
@ -77,8 +79,6 @@ declare namespace NodeJS {
|
|||||||
NEXT_PRIVATE_INNGEST_APP_ID?: string;
|
NEXT_PRIVATE_INNGEST_APP_ID?: string;
|
||||||
NEXT_PRIVATE_INNGEST_EVENT_KEY?: string;
|
NEXT_PRIVATE_INNGEST_EVENT_KEY?: string;
|
||||||
|
|
||||||
NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY?: string;
|
|
||||||
|
|
||||||
POSTGRES_URL?: string;
|
POSTGRES_URL?: string;
|
||||||
DATABASE_URL?: string;
|
DATABASE_URL?: string;
|
||||||
POSTGRES_PRISMA_URL?: string;
|
POSTGRES_PRISMA_URL?: string;
|
||||||
|
|||||||
@ -50,6 +50,7 @@
|
|||||||
"NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT",
|
"NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT",
|
||||||
"NEXT_PRIVATE_DATABASE_URL",
|
"NEXT_PRIVATE_DATABASE_URL",
|
||||||
"NEXT_PRIVATE_DIRECT_DATABASE_URL",
|
"NEXT_PRIVATE_DIRECT_DATABASE_URL",
|
||||||
|
"NEXT_PRIVATE_LOGGER_FILE_PATH",
|
||||||
"NEXT_PRIVATE_SIGNING_TRANSPORT",
|
"NEXT_PRIVATE_SIGNING_TRANSPORT",
|
||||||
"NEXT_PRIVATE_SIGNING_PASSPHRASE",
|
"NEXT_PRIVATE_SIGNING_PASSPHRASE",
|
||||||
"NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH",
|
"NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH",
|
||||||
@ -104,7 +105,6 @@
|
|||||||
"NEXT_PRIVATE_BROWSERLESS_URL",
|
"NEXT_PRIVATE_BROWSERLESS_URL",
|
||||||
"NEXT_PRIVATE_JOBS_PROVIDER",
|
"NEXT_PRIVATE_JOBS_PROVIDER",
|
||||||
"NEXT_PRIVATE_INNGEST_APP_ID",
|
"NEXT_PRIVATE_INNGEST_APP_ID",
|
||||||
"NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY",
|
|
||||||
"INNGEST_EVENT_KEY",
|
"INNGEST_EVENT_KEY",
|
||||||
"NEXT_PRIVATE_INNGEST_EVENT_KEY",
|
"NEXT_PRIVATE_INNGEST_EVENT_KEY",
|
||||||
"CI",
|
"CI",
|
||||||
|
|||||||
Reference in New Issue
Block a user