From bbe9caec4a7347ecff3d03398d7d1f1e3d213c1d Mon Sep 17 00:00:00 2001 From: AlbanSdl Date: Tue, 14 May 2024 17:05:01 +0200 Subject: [PATCH] maybe this will work --- web/.env.dist | 2 + web/dbml/schema.dbml | 2 +- web/package.json | 1 + web/pnpm-lock.yaml | 708 ++++++++++++++++++++++++++++++++++++++++++- web/schema.prisma | 10 +- web/src/app.ts | 249 ++++++++++----- 6 files changed, 878 insertions(+), 94 deletions(-) diff --git a/web/.env.dist b/web/.env.dist index 55348fd..c76ef3d 100644 --- a/web/.env.dist +++ b/web/.env.dist @@ -5,3 +5,5 @@ DATABASE_URL=mysql://dev:dev@localhost:3306/turbo_switch JWT_SECRET=1234 CAS_SERVICE=https://etu.utt.fr/dummyurl JWT_EXPIRES_IN=7y +SESAME_LENGTH=4 +SENTRY_DSN= \ No newline at end of file diff --git a/web/dbml/schema.dbml b/web/dbml/schema.dbml index d604fa3..b1647ab 100644 --- a/web/dbml/schema.dbml +++ b/web/dbml/schema.dbml @@ -16,7 +16,7 @@ Table Borrow { Table Opening { id Int [pk, increment] date DateTime - code String [not null] + code String codeGeneratedAt DateTime borrow Borrow return Borrow diff --git a/web/package.json b/web/package.json index f0c2c4f..8148c2a 100644 --- a/web/package.json +++ b/web/package.json @@ -7,6 +7,7 @@ }, "dependencies": { "@prisma/client": "^5.13.0", + "@sentry/node": "^8.0.0", "body-parser": "^1.20.2", "cookie-parser": "~1.4.6", "debug": "~2.6.9", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 4b7d377..1076e48 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@prisma/client': specifier: ^5.13.0 version: 5.13.0(prisma@5.13.0) + '@sentry/node': + specifier: ^8.0.0 + version: 8.0.0 body-parser: specifier: ^1.20.2 version: 1.20.2 @@ -167,11 +170,409 @@ packages: fastq: 1.17.1 dev: true + /@opentelemetry/api-logs@0.50.0: + resolution: {integrity: sha512-JdZuKrhOYggqOpUljAq4WWNi5nB10PmgoF0y2CvedLGXd0kSawb/UBnWT8gg1ND3bHCNHStAIVT0ELlxJJRqrA==} + engines: {node: '>=14'} + dependencies: + '@opentelemetry/api': 1.8.0 + dev: false + + /@opentelemetry/api-logs@0.51.1: + resolution: {integrity: sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==} + engines: {node: '>=14'} + dependencies: + '@opentelemetry/api': 1.8.0 + dev: false + /@opentelemetry/api@1.4.1: resolution: {integrity: sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==} engines: {node: '>=8.0.0'} dev: true + /@opentelemetry/api@1.8.0: + resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} + engines: {node: '>=8.0.0'} + dev: false + + /@opentelemetry/context-async-hooks@1.24.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-R5r6DO4kgEOVBxFXhXjwospLQkv+sYxwCfjvoZBe7Zm6KKXAV9kDSJhi/D1BweowdZmO+sdbENLs374gER8hpQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + dev: false + + /@opentelemetry/core@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/semantic-conventions': 1.23.0 + dev: false + + /@opentelemetry/core@1.24.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/semantic-conventions': 1.24.1 + dev: false + + /@opentelemetry/instrumentation-connect@0.35.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-COcQdFNVXyqaVGSuBgIyLu1qZUebjWyQhMAdMOOulCRznhquoyffeymQDZ0LB8XjD7kkG8if8PbykL4b8tjbNA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@types/connect': 3.4.36 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-express@0.35.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-ZmSB4WMd88sSecOL7DlghzdBl56/8ymb02n+xEJ/6zUgONuw/1uoTh1TAaNPKfEWdNLoLKXQm+Gd2zBrUVOX0w==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.48.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-fastify@0.35.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-lUHj4lYmJswKHR0twg3KFSiIkfTlF4tyh+VwyrrNDYy7yGDqzftP3tP4coVdhT78RRp3DpcAGggbfrIJbdP9pA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-graphql@0.39.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-TUe4DJJ2S89L45eO3esGrQKvIGVasj7gY4Nk7PecxkgeVnKO5gJ41mlbhUOF44vXxYQq53470FNnhe396+JlBQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-hapi@0.38.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-ZcOqEuwuutTDYIjhDIStix22ECblG/i9pHje23QGs4Q4YS4RMaZ5hKCoQJxW88Z4K7T53rQkdISmoXFKDV8xMg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-http@0.51.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-6b3nZnFFEz/3xZ6w8bVxctPUWIPWiXuPQ725530JgxnN1cvYFd8CJ75PrHZNjynmzSSnqBkN3ef4R9N+RpMh8Q==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-ioredis@0.40.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-Jv/fH7KhpWe4KBirsiqeUJIYrsdR2iu2l4nWhfOlRvaZ+zYIiLEzTQR6QhBbyRoAbU4OuYJzjWusOmmpGBnwng==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/redis-common': 0.36.2 + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-koa@0.39.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-eSqPzDykJVF9AcOuQvYqYCA/TN8tnU9/RYgrdPclaQcH6nfp0ZbQqLsAMGOwatfwJ8p06FAj+koPBy5NQNFMow==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@types/koa': 2.14.0 + '@types/koa__router': 12.0.3 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-mongodb@0.39.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-m9dMj39pcCshzlfCEn2lGrlNo7eV5fb9pGBnPyl/Am9Crh7Or8vOqvByCNd26Dgf5J978zTdLGF+6tM8j1WOew==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.48.0(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-mongoose@0.37.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-VBGfiERp2fxE35OjUFAlfAOKkPOwYx3FqqV8LG7mq6SGK6yhOaU7RvE1b//bhGWoVYohVyxaBIMRVZr4xpmOJQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-mysql2@0.37.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-KaXZr8B13IovmSN5Xe5qblp34VPsLaooivHMnhOwj2so7ivB1PcGGkesWH5knXC/9iQryiIFXwSDdHrd4R5iXQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0) + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-mysql@0.37.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-swp9B4oIOcduYfOslc7tbFDjOCgKlcSdVOO+emVnaOEvYG19NcGdc82WH6Zqmctl5oOEBVeKHS+wgjjbwBiMWA==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@types/mysql': 2.15.22 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-nestjs-core@0.36.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-ku1HdUWFwd6ajJh0pTPwDmcRZF8sbjLCTQXAjUTrJEfmiXavKHwFBZnyF9/5NWedK8FrfZjZ7+hH9heiDigMNQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation-pg@0.40.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-z3v8OzfImnycykWgqIdS44aUZlRwq51yYIo8GfmiRBd8yyMl2ESQyv6z/IAWBWyT015IWGy3ZTijySe65P9J1w==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.8.0) + '@types/pg': 8.6.1 + '@types/pg-pool': 2.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-S1uHE+sxaepgp+t8lvIDuRgyjJWisAb733198kwQTUc9ZtYQ2V2gmyCtR1x21ePGVLoMiX/NWY7WA290hwkjJQ==} + engines: {node: '>=14'} + requiresBuild: true + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@types/shimmer': 1.0.5 + import-in-the-middle: 1.4.2 + require-in-the-middle: 7.3.0 + semver: 7.6.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /@opentelemetry/instrumentation@0.48.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@types/shimmer': 1.0.5 + import-in-the-middle: 1.7.1 + require-in-the-middle: 7.3.0 + semver: 7.6.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation@0.50.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-bhGhbJiZKpuu7wTaSak4hyZcFPlnDeuSF/2vglze8B4w2LubcSbbOnkVTzTs5SXtzh4Xz8eRjaNnAm+u2GYufQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/api-logs': 0.50.0 + '@types/shimmer': 1.0.5 + import-in-the-middle: 1.7.1 + require-in-the-middle: 7.3.0 + semver: 7.6.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/api-logs': 0.51.1 + '@types/shimmer': 1.0.5 + import-in-the-middle: 1.7.4 + require-in-the-middle: 7.3.0 + semver: 7.6.2 + shimmer: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@opentelemetry/redis-common@0.36.2: + resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==} + engines: {node: '>=14'} + dev: false + + /@opentelemetry/resources@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.23.0 + dev: false + + /@opentelemetry/resources@1.24.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + dev: false + + /@opentelemetry/sdk-metrics@1.24.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) + lodash.merge: 4.6.2 + dev: false + + /@opentelemetry/sdk-trace-base@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.23.0 + dev: false + + /@opentelemetry/sdk-trace-base@1.24.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + dev: false + + /@opentelemetry/semantic-conventions@1.23.0: + resolution: {integrity: sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==} + engines: {node: '>=14'} + dev: false + + /@opentelemetry/semantic-conventions@1.24.1: + resolution: {integrity: sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==} + engines: {node: '>=14'} + dev: false + + /@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.1.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + dev: false + /@prisma/client@5.13.0(prisma@5.13.0): resolution: {integrity: sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg==} engines: {node: '>=16.13'} @@ -280,6 +681,16 @@ packages: dependencies: '@prisma/debug': 5.13.0 + /@prisma/instrumentation@5.13.0: + resolution: {integrity: sha512-MEJX1aWLsEjS+2iheBkEy1LlzQuUruPgKEzA9HPMwzitCoUUK1qn5o+yIphU7wWs47Le/cED0egYQL7y9/rSsA==} + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.50.0(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-trace-base': 1.23.0(@opentelemetry/api@1.8.0) + transitivePeerDependencies: + - supports-color + dev: false + /@prisma/internals@5.0.0: resolution: {integrity: sha512-VGWyFk6QlSBXT8z65Alq5F3o9E8IiTtaBoa3rmKkGpZjUk85kJy3jZz4xkRv53TaeghGE5rWfwkfak26KtY5yQ==} dependencies: @@ -335,6 +746,82 @@ packages: resolution: {integrity: sha512-JFdsnSgBPN8reDTLOI9Vh/6ccCb2aD1LbY/LWQnkcIgNo6IdpzvuM+qRVbBuA6IZP2SdqQI8Lu6RL2P8EFBQUA==} dev: true + /@sentry/core@8.0.0: + resolution: {integrity: sha512-PgOqQPdlIbiLFOo0F6IBzMbvusiEQ86+yXd76pIsuqQ2tj+iFL5gdYOckF/FKVpAwhfzIx64GKin2C+535c1qQ==} + engines: {node: '>=14.18'} + dependencies: + '@sentry/types': 8.0.0 + '@sentry/utils': 8.0.0 + dev: false + + /@sentry/node@8.0.0: + resolution: {integrity: sha512-yOmJV0gyRA5KMw4lUAuB2LytUwcwSByjFn2KO5Xy9Oc8XpgJ91CIU/v1Udv3GsrYo2HpdQn/dyZLwqqhbyM55Q==} + engines: {node: '>=14.18'} + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/context-async-hooks': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-connect': 0.35.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-express': 0.35.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-fastify': 0.35.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-graphql': 0.39.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-hapi': 0.38.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-http': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-ioredis': 0.40.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-koa': 0.39.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-mongodb': 0.39.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-mongoose': 0.37.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-mysql': 0.37.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-mysql2': 0.37.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-nestjs-core': 0.36.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation-pg': 0.40.0(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@prisma/instrumentation': 5.13.0 + '@sentry/core': 8.0.0 + '@sentry/opentelemetry': 8.0.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1)(@opentelemetry/instrumentation@0.51.1)(@opentelemetry/sdk-trace-base@1.24.1)(@opentelemetry/semantic-conventions@1.24.1) + '@sentry/types': 8.0.0 + '@sentry/utils': 8.0.0 + optionalDependencies: + opentelemetry-instrumentation-fetch-node: 1.2.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@sentry/opentelemetry@8.0.0(@opentelemetry/api@1.8.0)(@opentelemetry/core@1.24.1)(@opentelemetry/instrumentation@0.51.1)(@opentelemetry/sdk-trace-base@1.24.1)(@opentelemetry/semantic-conventions@1.24.1): + resolution: {integrity: sha512-AvUUZpiJTq3H69Hd9k0tiOqGTA87uq0wZN+WaV4iT6sItG2MVaqYup5wSmqNKD6iVErfx7djzZ5C3LWsFQX3KQ==} + engines: {node: '>=14.18'} + peerDependencies: + '@opentelemetry/api': ^1.8.0 + '@opentelemetry/core': ^1.24.1 + '@opentelemetry/instrumentation': ^0.51.1 + '@opentelemetry/sdk-trace-base': ^1.23.0 + '@opentelemetry/semantic-conventions': ^1.23.0 + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + '@sentry/core': 8.0.0 + '@sentry/types': 8.0.0 + '@sentry/utils': 8.0.0 + dev: false + + /@sentry/types@8.0.0: + resolution: {integrity: sha512-Dtd8dtFEq1XtdAntkguYHaL4tokzm4Aq5t0HP6Vl1P+MPImokDE1UcpKglkh0Z5aym/vF6e0qW9/CM7lAI5R/A==} + engines: {node: '>=14.18'} + dev: false + + /@sentry/utils@8.0.0: + resolution: {integrity: sha512-oZex/dRKfkWHoK99W7QDQtr26IZrAD9EDd2+pwLmkFclApxVDGLLKNkmcbfj4LX1zMROxKWww/GTE7eo08tEKg==} + engines: {node: '>=14.18'} + dependencies: + '@sentry/types': 8.0.0 + dev: false + /@tsconfig/node10@1.0.11: resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} dev: false @@ -351,6 +838,12 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: false + /@types/accepts@1.3.7: + resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} + dependencies: + '@types/node': 20.12.12 + dev: false + /@types/babel-types@7.0.15: resolution: {integrity: sha512-JUgfZHUOMbtjopxiOQaaF+Uovk5wpDqpXR+XLWiOivCWSy1FccO30lvNNpCt8geFwq8VmGT2y9OMkOpA0g5O5g==} dev: false @@ -366,13 +859,21 @@ packages: dependencies: '@types/connect': 3.4.38 '@types/node': 20.12.12 - dev: true + + /@types/connect@3.4.36: + resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} + dependencies: + '@types/node': 20.12.12 + dev: false /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: '@types/node': 20.12.12 - dev: true + + /@types/content-disposition@0.5.8: + resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==} + dev: false /@types/cookie-parser@1.4.7: resolution: {integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==} @@ -380,6 +881,15 @@ packages: '@types/express': 4.17.21 dev: true + /@types/cookies@0.9.0: + resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==} + dependencies: + '@types/connect': 3.4.38 + '@types/express': 4.17.21 + '@types/keygrip': 1.0.6 + '@types/node': 20.12.12 + dev: false + /@types/cross-spawn@6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: @@ -399,7 +909,6 @@ packages: '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 - dev: true /@types/express@4.17.21: resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} @@ -408,11 +917,13 @@ packages: '@types/express-serve-static-core': 4.19.0 '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 - dev: true + + /@types/http-assert@1.5.5: + resolution: {integrity: sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==} + dev: false /@types/http-errors@2.0.4: resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - dev: true /@types/jsonwebtoken@9.0.6: resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==} @@ -420,14 +931,48 @@ packages: '@types/node': 20.12.12 dev: true + /@types/keygrip@1.0.6: + resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==} + dev: false + + /@types/koa-compose@3.2.8: + resolution: {integrity: sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==} + dependencies: + '@types/koa': 2.14.0 + dev: false + + /@types/koa@2.14.0: + resolution: {integrity: sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==} + dependencies: + '@types/accepts': 1.3.7 + '@types/content-disposition': 0.5.8 + '@types/cookies': 0.9.0 + '@types/http-assert': 1.5.5 + '@types/http-errors': 2.0.4 + '@types/keygrip': 1.0.6 + '@types/koa-compose': 3.2.8 + '@types/node': 20.12.12 + dev: false + + /@types/koa__router@12.0.3: + resolution: {integrity: sha512-5YUJVv6NwM1z7m6FuYpKfNLTZ932Z6EF6xy2BbtpJSyn13DKNQEkXVffFVSnJHxvwwWh2SAeumpjAYUELqgjyw==} + dependencies: + '@types/koa': 2.14.0 + dev: false + /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - dev: true /@types/ms@0.7.34: resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} dev: true + /@types/mysql@2.15.22: + resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==} + dependencies: + '@types/node': 20.12.12 + dev: false + /@types/node@20.12.12: resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} dependencies: @@ -437,13 +982,25 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true + /@types/pg-pool@2.0.4: + resolution: {integrity: sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==} + dependencies: + '@types/pg': 8.6.1 + dev: false + + /@types/pg@8.6.1: + resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} + dependencies: + '@types/node': 20.12.12 + pg-protocol: 1.6.1 + pg-types: 2.2.0 + dev: false + /@types/qs@6.9.15: resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - dev: true /@types/range-parser@1.2.7: resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - dev: true /@types/retry@0.12.0: resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} @@ -454,7 +1011,6 @@ packages: dependencies: '@types/mime': 1.3.5 '@types/node': 20.12.12 - dev: true /@types/serve-static@1.15.7: resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} @@ -462,7 +1018,10 @@ packages: '@types/http-errors': 2.0.4 '@types/node': 20.12.12 '@types/send': 0.17.4 - dev: true + + /@types/shimmer@1.0.5: + resolution: {integrity: sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==} + dev: false /@types/strip-bom@3.0.0: resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} @@ -490,6 +1049,22 @@ packages: acorn: 4.0.13 dev: false + /acorn-import-assertions@1.9.0(acorn@8.11.3): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: false + + /acorn-import-attributes@1.9.5(acorn@8.11.3): + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: false + /acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -858,6 +1433,10 @@ packages: engines: {node: '>=8'} dev: true + /cjs-module-lexer@1.3.1: + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + dev: false + /clean-css@3.4.28: resolution: {integrity: sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==} engines: {node: '>=0.10.0'} @@ -1055,7 +1634,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} @@ -1597,6 +2175,35 @@ packages: engines: {node: '>= 4'} dev: true + /import-in-the-middle@1.4.2: + resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} + requiresBuild: true + dependencies: + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + cjs-module-lexer: 1.3.1 + module-details-from-path: 1.0.3 + dev: false + optional: true + + /import-in-the-middle@1.7.1: + resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} + dependencies: + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + cjs-module-lexer: 1.3.1 + module-details-from-path: 1.0.3 + dev: false + + /import-in-the-middle@1.7.4: + resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==} + dependencies: + acorn: 8.11.3 + acorn-import-attributes: 1.9.5(acorn@8.11.3) + cjs-module-lexer: 1.3.1 + module-details-from-path: 1.0.3 + dev: false + /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} @@ -1870,6 +2477,10 @@ packages: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} dev: false + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: false + /lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} dev: false @@ -1990,6 +2601,10 @@ packages: hasBin: true dev: false + /module-details-from-path@1.0.3: + resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} + dev: false + /moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} dev: false @@ -2013,7 +2628,6 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2149,6 +2763,19 @@ packages: is-wsl: 2.2.0 dev: true + /opentelemetry-instrumentation-fetch-node@1.2.0: + resolution: {integrity: sha512-aiSt/4ubOTyb1N5C2ZbGrBvaJOXIZhZvpRPYuUVxQJe27wJZqf/o65iPrqgLcgfeOLaQ8cS2Q+762jrYvniTrA==} + engines: {node: '>18.0.0'} + requiresBuild: true + dependencies: + '@opentelemetry/api': 1.8.0 + '@opentelemetry/instrumentation': 0.43.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.24.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + /p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -2250,6 +2877,26 @@ packages: engines: {node: '>=8'} dev: true + /pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + dev: false + + /pg-protocol@1.6.1: + resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} + dev: false + + /pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + dev: false + /picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} dev: true @@ -2265,6 +2912,28 @@ packages: find-up: 4.1.0 dev: true + /postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + dev: false + + /postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + dev: false + + /postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + dev: false + + /postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + dependencies: + xtend: 4.0.2 + dev: false + /prisma-dbml-generator@0.12.0: resolution: {integrity: sha512-b5CqA9cCY5jmNJGjx8oUbPw3KSgVd+mu8711MSZIRY9dIF0Vlcs/Au6LR3S5guncydM7Zkh8iz8vC+c2CDj3Xw==} hasBin: true @@ -2515,6 +3184,17 @@ packages: engines: {node: '>=8'} dev: true + /require-in-the-middle@7.3.0: + resolution: {integrity: sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==} + engines: {node: '>=8.6.0'} + dependencies: + debug: 4.3.4 + module-details-from-path: 1.0.3 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: false + /resolve@1.22.2: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} hasBin: true @@ -2665,6 +3345,10 @@ packages: engines: {node: '>=8'} dev: true + /shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + dev: false + /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} diff --git a/web/schema.prisma b/web/schema.prisma index e9ff068..63fad34 100644 --- a/web/schema.prisma +++ b/web/schema.prisma @@ -24,12 +24,12 @@ model Borrow { } model Opening { - id Int @id @default(autoincrement()) - date DateTime? - code String? + id Int @id @default(autoincrement()) + date DateTime? + code String? codeGeneratedAt DateTime? - borrow Borrow? @relation("borrowOpening") - return Borrow? @relation("borrowClosing") + borrow Borrow? @relation("borrowOpening") + return Borrow? @relation("borrowClosing") } model User { diff --git a/web/src/app.ts b/web/src/app.ts index 644abbf..54de875 100644 --- a/web/src/app.ts +++ b/web/src/app.ts @@ -1,24 +1,13 @@ -import express, { Request, Response, Router } from 'express'; -import dotenv from 'dotenv'; +import express, { Request, Response, Router } from "express"; +import dotenv from "dotenv"; import { PrismaClient } from "@prisma/client"; import path from "path"; -import cookieParser from 'cookie-parser'; -import jwt, {TokenExpiredError} from 'jsonwebtoken'; -import {XMLParser} from "fast-xml-parser"; -import bodyParser from 'body-parser'; - -// import * as Sentry from '@sentry/node'; -// import cors from 'cors'; -// import helmet from 'helmet'; - -// import { notFound } from './utils/responses'; -// import { Error } from './types'; -// import router from './controllers'; -// import { morgan } from './utils/logger'; -// import { initUserRequest } from './middlewares/user'; -// import errorHandler from './middlewares/errorHandler'; -// import { enforceQueryString } from './middlewares/validation'; -// import rateLimiter from './middlewares/ratelimiter'; +import cookieParser from "cookie-parser"; +import jwt from "jsonwebtoken"; +import { XMLParser } from "fast-xml-parser"; +import bodyParser from "body-parser"; +import logger from "./logger"; +import * as Sentry from "@sentry/node"; const prisma = new PrismaClient(); dotenv.config(); @@ -27,13 +16,17 @@ const app = express(); const webRouter = Router(); function authenticate(request: Request) { - if (!request.cookies['token']) { + if (!request.cookies["token"]) { return null; } try { - return (jwt.verify(request.cookies['token'], process.env.JWT_SECRET) as {login: string}).login; + return ( + jwt.verify(request.cookies["token"], process.env.JWT_SECRET) as { + login: string; + } + ).login; } catch (e) { - return null + return null; } } @@ -49,103 +42,207 @@ const currentlyBorrowing = { async function generateCode() { let code: string; let found; - const ciffers = '0123456789'; + const ciffers = "0123456789"; do { - code = ciffers[Math.floor(Math.random() * 10)] + ciffers[Math.floor(Math.random() * 10)] + ciffers[Math.floor(Math.random() * 10)] + ciffers[Math.floor(Math.random() * 10)]; - found = await prisma.opening.findFirst({where: {code}}); - } while (found) + code = + ciffers[Math.floor(Math.random() * 10)] + + ciffers[Math.floor(Math.random() * 10)] + + ciffers[Math.floor(Math.random() * 10)] + + ciffers[Math.floor(Math.random() * 10)]; + found = await prisma.opening.findFirst({ where: { code } }); + } while (found); return code; } async function getJoyconsLeft() { - const joyconBorrows = await prisma.borrow.findMany({where: {borrowOpening: {OR: [validOpening, {date: {not: null}}]}, returnOpening: {date: {gte: new Date(Date.now())}}}}); - return Number.parseInt(process.env.TOTAL_JOYCONS) - joyconBorrows.reduce((acc, borrow) => acc + borrow.joyconsTaken, 0); + const joyconBorrows = await prisma.borrow.findMany({ + where: { + borrowOpening: { OR: [validOpening, { date: { not: null } }] }, + returnOpening: { date: { gte: new Date(Date.now()) } }, + }, + }); + return ( + Number.parseInt(process.env.TOTAL_JOYCONS) - + joyconBorrows.reduce((acc, borrow) => acc + borrow.joyconsTaken, 0) + ); } -webRouter.get('/', async (request: Request, response: Response) => { +webRouter.get("/", async (request: Request, response: Response) => { const login = authenticate(request); if (!login) { - return response.redirect('/login'); + return response.redirect("/login"); } - const borrow = await prisma.borrow.findFirst({where: { user: {login}, ...currentlyBorrowing}}); + const borrow = await prisma.borrow.findFirst({ + where: { user: { login }, ...currentlyBorrowing }, + }); if (!borrow) { - return response.sendFile(path.join(__dirname, '../www/borrow.html')); + return response.sendFile(path.join(__dirname, "../www/borrow.html")); } - if (request.query['code']) { - return response.sendFile(path.join(__dirname, '../www/giveBack.html')); + if (request.query["code"]) { + return response.sendFile(path.join(__dirname, "../www/giveBack.html")); } const code = await generateCode(); - await prisma.opening.upsert({where: {id: borrow.id}, create: {code, codeGeneratedAt: new Date(Date.now())}, update: {code, codeGeneratedAt: new Date(Date.now())}}); + await prisma.opening.upsert({ + where: { id: borrow.id }, + create: { code, codeGeneratedAt: new Date(Date.now()) }, + update: { code, codeGeneratedAt: new Date(Date.now()) }, + }); return response.redirect(`/?code=${code}`); }); -webRouter.get('/login', async (request: Request, response: Response) => { +webRouter.get("/login", async (request: Request, response: Response) => { if (authenticate(request)) { - return response.redirect('/'); + return response.redirect("/"); } - if (request.query['ticket']) { - const res = await fetch(`https://cas.utt.fr/cas/serviceValidate?service=${encodeURI(process.env.CAS_SERVICE)}&ticket=${request.query['ticket']}`) + if (request.query["ticket"]) { + const res = await fetch( + `https://cas.utt.fr/cas/serviceValidate?service=${encodeURI( + process.env.CAS_SERVICE + )}&ticket=${request.query["ticket"]}` + ); const resData: { - ['cas:serviceResponse']: + ["cas:serviceResponse"]: | { - ['cas:authenticationSuccess']: { - ['cas:attributes']: { - 'cas:uid': string; - 'cas:mail': string; - 'cas:sn': string; - 'cas:givenName': string; - }; - }; - } - | { 'cas:authenticationFailure': unknown }; + ["cas:authenticationSuccess"]: { + ["cas:attributes"]: { + "cas:uid": string; + "cas:mail": string; + "cas:sn": string; + "cas:givenName": string; + }; + }; + } + | { "cas:authenticationFailure": unknown }; } = new XMLParser().parse(await res.text()); - if ('cas:authenticationFailure' in resData['cas:serviceResponse']) { - return { status: 'invalid', token: '' }; + if ("cas:authenticationFailure" in resData["cas:serviceResponse"]) { + return { status: "invalid", token: "" }; } const userData = { - login: resData['cas:serviceResponse']['cas:authenticationSuccess']['cas:attributes']['cas:uid'], - mail: resData['cas:serviceResponse']['cas:authenticationSuccess']['cas:attributes']['cas:mail'], - lastName: resData['cas:serviceResponse']['cas:authenticationSuccess']['cas:attributes']['cas:sn'], - firstName: resData['cas:serviceResponse']['cas:authenticationSuccess']['cas:attributes']['cas:givenName'], + login: + resData["cas:serviceResponse"]["cas:authenticationSuccess"][ + "cas:attributes" + ]["cas:uid"], + mail: resData["cas:serviceResponse"]["cas:authenticationSuccess"][ + "cas:attributes" + ]["cas:mail"], + lastName: + resData["cas:serviceResponse"]["cas:authenticationSuccess"][ + "cas:attributes" + ]["cas:sn"], + firstName: + resData["cas:serviceResponse"]["cas:authenticationSuccess"][ + "cas:attributes" + ]["cas:givenName"], // TODO : fetch other infos from LDAP }; - let user = await prisma.user.findUnique({where: {login: userData.login}}); + let user = await prisma.user.findUnique({ + where: { login: userData.login }, + }); if (!user) { - await prisma.user.create({data: userData}); + await prisma.user.create({ data: userData }); } - const token = jwt.sign({login: userData.login}, process.env.JWT_SECRET, {expiresIn: process.env.JWT_EXPIRES_IN}); - return response.cookie('token', token).redirect('/'); + const token = jwt.sign({ login: userData.login }, process.env.JWT_SECRET, { + expiresIn: process.env.JWT_EXPIRES_IN, + }); + return response.cookie("token", token).redirect("/"); } - return response.sendFile(path.join(__dirname, '../www/login.html')); + return response.sendFile(path.join(__dirname, "../www/login.html")); }); -webRouter.get('/login/cas', async (request: Request, response: Response) => { - return response.redirect(`https://cas.utt.fr/cas/login?service=${encodeURI(process.env.CAS_SERVICE)}`) -}) +webRouter.get("/login/cas", async (request: Request, response: Response) => { + return response.redirect( + `https://cas.utt.fr/cas/login?service=${encodeURI(process.env.CAS_SERVICE)}` + ); +}); -webRouter.post('/', async (request: Request, response: Response) => { +webRouter.post("/", async (request: Request, response: Response) => { const login = authenticate(request); if (!login) { - return response.redirect('/login'); + return response.redirect("/login"); } const joycons = Number.parseInt(request.body.joycons); - if (joycons < 0 || joycons > await getJoyconsLeft()) { - return response.send(`Il ne reste plus que ${getJoyconsLeft()} joycons disponibles`); + const joyconsLeft = await getJoyconsLeft(); + if (joycons < 0 || joycons > joyconsLeft) { + return response.send( + `Il ne reste plus que ${joyconsLeft} joycons disponibles` + ); } const code = await generateCode(); - await prisma.borrow.create({data: {joyconsTaken: joycons, borrowOpening: {create: {code}}, returnOpening: {create: {}}, user: {connect: {login}}}}); + await prisma.borrow.create({ + data: { + joyconsTaken: joycons, + borrowOpening: { + create: { + code, + codeGeneratedAt: new Date(), + }, + }, + returnOpening: { create: {} }, + user: { connect: { login } }, + }, + }); return response.redirect(`/?code=${code}`); }); const apiRouter = Router(); -apiRouter.post('/sesame', (request: Request, response: Response) => { - response.send('Open Sesame'); +apiRouter.post("/sesame", async (request: Request, response: Response) => { + const sesame: string | undefined = request.body.code; + if (!sesame) return response.status(400).send("Missing code"); + if ( + typeof sesame !== "string" || + sesame.length !== (Number(process.env.SESAME_LENGTH) || 4) + ) + return response.status(400).send("Invalid code"); + + const [opening] = await prisma.opening.findMany({ + where: { + code: sesame, + date: null, + codeGeneratedAt: new Date(Date.now() - 1000 * 60 * 5), + }, + select: { + return: { + select: { + returnOpeningId: true, + }, + }, + }, + }); + + if (!opening) { + logger.info(`Invalid Sesame provided : ${sesame}`); + return response.status(403).send("Invalid sesame"); + } + + if (opening.return) { + const returnCode = await generateCode(); + await prisma.opening.update({ + where: { + id: opening.return.returnOpeningId, + }, + data: { + code: returnCode, + codeGeneratedAt: new Date(), + }, + }); + } + + return response.status(200).send("Sésame ouvre toi"); }); -// Initiate Sentry -// Sentry.init({ dsn: env.log.sentryDsn, environment: env.environment }); -// app.use(Sentry.Handlers.requestHandler({})); +if (process.env.SENTRY_DSN) { + // Initiate Sentry + Sentry.init({ + dsn: process.env.SENTRY_DSN, + environment: process.env.NODE_ENV, + // Set tracesSampleRate to 1.0 to capture 100% + // of transactions for performance monitoring. + // We recommend adjusting this value in production + tracesSampleRate: 1.0, + }); + Sentry.setupExpressErrorHandler(app); +} // Enable morgan logger // app.use(morgan()); @@ -156,10 +253,10 @@ apiRouter.post('/sesame', (request: Request, response: Response) => { // Security middlewares // app.use(cors(), helmet()); -app.use('', cookieParser()); +app.use("", cookieParser()); app.use(bodyParser.urlencoded({ extended: true })); -app.use('', webRouter); +app.use("", webRouter); // Main routes app.use(process.env.API_PREFIX, apiRouter);