From ea078c038e82537745fe768c38c082d40f8de68a Mon Sep 17 00:00:00 2001 From: hgorges Date: Sun, 18 Aug 2024 19:00:23 +0200 Subject: [PATCH] Changing docker settings to transpile locally --- .dockerignore | 24 --- .eslintrc.json | 12 +- .gitignore | 2 +- .prettierrc.json | 2 +- Dockerfile | 13 +- db/data-model.drawio | 73 -------- docker-compose.yml | 29 ++-- nodemon.json | 7 +- package-lock.json | 158 +++++++++++------- package.json | 14 +- public/css/content/admin.css | 8 +- .../css/content/dashboard/calendar-widget.css | 4 +- .../css/content/dashboard/traffic-widget.css | 4 +- .../css/content/dashboard/weather-widget.css | 8 +- public/css/content/signup.css | 2 +- public/css/main.css | 4 +- qodana.yaml | 2 +- {db => src/db}/knexfile.ts | 4 +- .../db}/migrations/001_settings_migration.ts | 0 .../db}/migrations/002_users_migration.ts | 0 .../db}/migrations/003_api_keys_migration.ts | 0 {db => src/db}/seeds/001_users_seed.ts | 5 + src/middleware/authMiddleware.ts | 2 +- src/server.ts | 50 +++--- src/utils/mailer.ts | 8 + tsconfig.json | 15 +- views/includes/end.ejs | 2 +- 27 files changed, 201 insertions(+), 251 deletions(-) delete mode 100644 .dockerignore delete mode 100644 db/data-model.drawio rename {db => src/db}/knexfile.ts (85%) rename {db => src/db}/migrations/001_settings_migration.ts (100%) rename {db => src/db}/migrations/002_users_migration.ts (100%) rename {db => src/db}/migrations/003_api_keys_migration.ts (100%) rename {db => src/db}/seeds/001_users_seed.ts (88%) create mode 100644 src/utils/mailer.ts diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 72cd8e1..0000000 --- a/.dockerignore +++ /dev/null @@ -1,24 +0,0 @@ -**/.classpath -**/.coverage -**/.dockerignore -**/.env -**/.git -**/.gitignore -**/.project -**/.settings -**/.toolstarget -**/.vs -**/.vscode -**/*.*proj.user -**/*.dbmdl -**/*.jfm -**/charts -**/docker-compose* -**/Dockerfile* -**/node_modules -**/npm-debug.log -**/obj -**/secrets.dev.yml -**/values.dev.yml -LICENSE -README.md diff --git a/.eslintrc.json b/.eslintrc.json index 16b6531..d1597f3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,9 @@ "root": true, "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], "parser": "@typescript-eslint/parser", - "parserOptions": { "project": ["./tsconfig.json"] }, + "parserOptions": { + "project": ["./tsconfig.json"] + }, "plugins": ["@typescript-eslint"], "rules": { "@typescript-eslint/strict-boolean-expressions": [ @@ -27,9 +29,11 @@ "@typescript-eslint/no-explicit-any": "off" }, "ignorePatterns": [ - "src/**/*.test.ts", - "public/js/**/*.js", "coverage/**/*.js", - "jest.config.ts" + "dist/**/*.js", + "public/js/**/*.js", + "jest.config.ts", + // Ignore test files + "test/*" ] } diff --git a/.gitignore b/.gitignore index fa3bbac..bfd4297 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea/ coverage/ node_modules/ -out/ +dist/ secrets/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 3923e53..f5b3d30 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -6,7 +6,7 @@ "useTabs": false, "overrides": [ { - "files": ["*.json", "*.yml"], + "files": ["*.json", "*.{yml,yaml}"], "options": { "tabWidth": 2 } diff --git a/Dockerfile b/Dockerfile index 3b6f17f..a3c7a26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,15 +6,6 @@ WORKDIR /app COPY package*.json ./ -RUN npm install && npm cache clean --force +RUN npm install -COPY tsconfig.json ./ -COPY nodemon.json ./ - -COPY ./src ./src -COPY ./db ./db -COPY ./public ./public -COPY ./views ./views -COPY ./secrets ./secrets - -RUN npm run build +CMD [ "npm", "start" ] diff --git a/db/data-model.drawio b/db/data-model.drawio deleted file mode 100644 index ea6798d..0000000 --- a/db/data-model.drawio +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docker-compose.yml b/docker-compose.yml index 57bf950..53279ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,21 +1,20 @@ -version: '3.8' - services: server: image: daily-dash restart: always - build: - context: . - dockerfile: Dockerfile - pull_policy: never - command: sh -c "npm run migrate && npm start" ports: - ${PORT}:443 - ${DEBUG_PORT}:${DEBUG_PORT} volumes: - - ./src:/app/src + - ./dist:/app/dist + - ./nodemon.json:/app/nodemon.json - ./public:/app/public - ./views:/app/views + - ./secrets:/app/secrets + build: + context: . + dockerfile: Dockerfile + pull_policy: never env_file: ./secrets/.env depends_on: db: @@ -26,35 +25,35 @@ services: db: image: postgres:latest restart: always + ports: + - ${DB_PORT}:5432 volumes: - db-data:/var/lib/postgresql/data + env_file: ./secrets/.env environment: POSTGRES_DB: ${DB_NAME} POSTGRES_USER: ${DB_USERNAME} POSTGRES_PASSWORD: ${DB_PASSWORD} - ports: - - ${DB_PORT}:5432 healthcheck: - test: [ 'CMD', 'pg_isready', '-U', '$DB_USERNAME' ] + test: ['CMD', 'pg_isready', '-U', '$DB_USERNAME'] interval: 10s timeout: 5s retries: 5 - env_file: ./secrets/.env cache: image: redis:latest restart: always ports: - ${REDIS_PORT}:6379 - command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD} volumes: - cache-data:/data + env_file: ./secrets/.env + command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD} healthcheck: - test: [ 'CMD', 'redis-cli', '--raw', 'incr', 'ping' ] + test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping'] interval: 10s timeout: 5s retries: 5 - env_file: ./secrets/.env volumes: db-data: diff --git a/nodemon.json b/nodemon.json index c0d6539..651bbb0 100644 --- a/nodemon.json +++ b/nodemon.json @@ -1,6 +1,7 @@ { - "watch": ["src"], - "ext": ".ts,.js", + "watch": ["dist"], + "ext": ".js", "ignore": [], - "exec": "node -r ts-node/register --inspect=0.0.0.0:9229" + "exec": "node --inspect=0.0.0.0:9229 ./dist/server.js", + "legacyWatch": true } diff --git a/package-lock.json b/package-lock.json index 4c84ea9..98f5eb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "daily-dash", "version": "1.0.0", - "license": "ISC", + "license": "GPLv3", "dependencies": { "@google-cloud/local-auth": "^3.0.1", "@googleapis/calendar": "^9.7.0", @@ -62,6 +62,7 @@ "@types/serve-favicon": "^2.5.7", "@types/supertest": "^2.0.16", "@types/xml-js": "^1.0.0", + "@types/xml2js": "^0.4.14", "@typescript-eslint/eslint-plugin": "^7.0.2", "jest": "^29.7.0", "nodemon": "^3.0.1", @@ -418,6 +419,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", @@ -529,6 +560,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -768,9 +814,9 @@ } }, "node_modules/@googleapis/calendar": { - "version": "9.7.6", - "resolved": "https://registry.npmjs.org/@googleapis/calendar/-/calendar-9.7.6.tgz", - "integrity": "sha512-8Mt+Vgm7ybDmU+ezAiLzeO6hxZZkt2hMY+bS/1OZeYM6moHUQAF5cFTOWiVk63U+HJji8dKt9XvscOxEWAwnrQ==", + "version": "9.7.7", + "resolved": "https://registry.npmjs.org/@googleapis/calendar/-/calendar-9.7.7.tgz", + "integrity": "sha512-PPXjXlnZqyZv1+1SstLLTOBvro5HuXAsNGwjdB+2VXmJH3DjPvdCiq3i7DJkCi19tcpddzW6Oq9FM1bpUZHq3A==", "dependencies": { "googleapis-common": "^7.0.0" }, @@ -779,9 +825,9 @@ } }, "node_modules/@googleapis/docs": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@googleapis/docs/-/docs-3.0.2.tgz", - "integrity": "sha512-7AjDSKcZlmt+3cE+t2+kRmDyySl1sCyDYxfnWCY9rpSUhuEFRT7foqdGscI/H2f1blw3LSnF7SVvaYYHlfVHNg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@googleapis/docs/-/docs-3.1.0.tgz", + "integrity": "sha512-8tw3nT0ppvElnIEOByijz/kpOoLDUazQVNxP2ZmaXStPfP1VVPaAqz7KQfiZM3e3fFhe+0eYoTv3a93XUf9auA==", "dependencies": { "googleapis-common": "^7.0.0" }, @@ -1835,11 +1881,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", - "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "version": "20.16.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.0.tgz", + "integrity": "sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/nodemailer": { @@ -1979,6 +2025,15 @@ "xml-js": "*" } }, + "node_modules/@types/xml2js": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", + "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -2504,9 +2559,9 @@ "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2728,23 +2783,26 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -3115,9 +3173,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001649", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001649.tgz", - "integrity": "sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -3924,9 +3982,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", - "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", + "version": "1.5.11", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz", + "integrity": "sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==", "dev": true }, "node_modules/emittery": { @@ -4832,9 +4890,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -5002,15 +5060,15 @@ } }, "node_modules/gaxios": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", - "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^10.0.0" + "uuid": "^9.0.1" }, "engines": { "node": ">=14" @@ -5039,18 +5097,6 @@ "node": ">= 14" } }, - "node_modules/gaxios/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/gcp-metadata": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", @@ -5821,9 +5867,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" @@ -9926,9 +9972,9 @@ } }, "node_modules/type-fest": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz", - "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==", + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.25.0.tgz", + "integrity": "sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==", "dev": true, "peer": true, "engines": { @@ -9981,9 +10027,9 @@ "dev": true }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.19.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", + "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==" }, "node_modules/universalify": { "version": "0.1.2", diff --git a/package.json b/package.json index 93a84e1..da0ff3d 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "description": "Your all-in-one dashboard for news, weather, todos, events, and commuting.", "main": "./src/server.ts", "scripts": { - "clean": "rimraf ./out", - "build": "tsc", - "start": "nodemon -L ./src/server.ts", + "clean": "rimraf ./dist", + "build": "tsc --watch", + "start": "nodemon", "test": "jest", "lint": "eslint .", "format:check": "prettier . --check", @@ -15,8 +15,7 @@ "docker:up": "docker compose --env-file ./secrets/.env up", "docker:down": "docker-compose --env-file ./secrets/.env down", "docker:rmi": "docker rmi daily-dash postgres redis", - "migrate": "knex --knexfile ./out/db/knexfile.js migrate:latest", - "seed": "knex --knexfile ./out/db/knexfile.js seed:run" + "seed": "knex --knexfile ./dist/db/knexfile.js seed:run" }, "repository": { "type": "git", @@ -31,8 +30,8 @@ "calendar", "commuting" ], - "author": "CryptoSpaceDev", - "license": "ISC", + "author": "Hannes Gorges", + "license": "GPLv3", "bugs": { "url": "https://github.com/hgorges/DailyDash.git/issues" }, @@ -55,6 +54,7 @@ "@types/serve-favicon": "^2.5.7", "@types/supertest": "^2.0.16", "@types/xml-js": "^1.0.0", + "@types/xml2js": "^0.4.14", "@typescript-eslint/eslint-plugin": "^7.0.2", "jest": "^29.7.0", "nodemon": "^3.0.1", diff --git a/public/css/content/admin.css b/public/css/content/admin.css index ff5971b..201b105 100644 --- a/public/css/content/admin.css +++ b/public/css/content/admin.css @@ -1,10 +1,10 @@ - .content-container { display: flex; justify-content: space-between; } -#dashboard-summary, #user-list { +#dashboard-summary, +#user-list { flex: 1; margin: 10px; } @@ -70,7 +70,7 @@ } .stat:after { - content: ""; + content: ''; display: table; clear: both; -} \ No newline at end of file +} diff --git a/public/css/content/dashboard/calendar-widget.css b/public/css/content/dashboard/calendar-widget.css index e405f01..185026d 100644 --- a/public/css/content/dashboard/calendar-widget.css +++ b/public/css/content/dashboard/calendar-widget.css @@ -45,7 +45,7 @@ justify-content: space-between; background: var(--secondary-color); color: var(--primary-color); - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); transition: transform 0.2s ease, box-shadow 0.2s ease; margin-bottom: 10px; @@ -53,7 +53,7 @@ .event:hover { transform: translateY(-3px); - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); } .event h3 { diff --git a/public/css/content/dashboard/traffic-widget.css b/public/css/content/dashboard/traffic-widget.css index 1b09dd6..5b79501 100644 --- a/public/css/content/dashboard/traffic-widget.css +++ b/public/css/content/dashboard/traffic-widget.css @@ -3,7 +3,7 @@ border-left: 4px solid var(--primary-color); padding: 10px 20px; border-radius: 8px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); } .route-info { @@ -34,7 +34,7 @@ border-radius: 20px; padding: 5px 10px; margin: 5px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); display: inline-flex; align-items: center; font-size: 1em; diff --git a/public/css/content/dashboard/weather-widget.css b/public/css/content/dashboard/weather-widget.css index e78da19..03793f5 100644 --- a/public/css/content/dashboard/weather-widget.css +++ b/public/css/content/dashboard/weather-widget.css @@ -19,7 +19,7 @@ background-color: var(--secondary-color); color: var(--primary-color); border-radius: 5px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); } .weather-description:not(:last-child) { @@ -44,7 +44,7 @@ background-color: var(--secondary-color); color: var(--primary-color); border-radius: 5px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); } .temperature-label { @@ -72,7 +72,7 @@ padding: 10px; background: var(--secondary-color); border-radius: 10px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -121,7 +121,7 @@ padding: 10px; background: var(--secondary-color); border-radius: 10px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); width: 25px; height: 25px; display: flex; diff --git a/public/css/content/signup.css b/public/css/content/signup.css index 89fb24f..9d8629b 100644 --- a/public/css/content/signup.css +++ b/public/css/content/signup.css @@ -87,7 +87,7 @@ color: var(--error-color); border-radius: 8px; margin: 10px 10px 20px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); font-weight: bold; position: relative; border-left: 4px solid var(--error-color); diff --git a/public/css/main.css b/public/css/main.css index 5b93047..f72686f 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -79,7 +79,7 @@ p { color: var(--info-color); border-radius: 8px; margin: 10px 10px 20px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); font-weight: bold; position: relative; border-left: 4px solid var(--info-color); @@ -91,7 +91,7 @@ p { color: var(--error-color); border-radius: 8px; margin: 10px 10px 20px; - box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); font-weight: bold; position: relative; border-left: 4px solid var(--error-color); diff --git a/qodana.yaml b/qodana.yaml index 51c2bcb..6013899 100644 --- a/qodana.yaml +++ b/qodana.yaml @@ -1,4 +1,4 @@ -version: "1.0" +version: '1.0' profile: name: qodana.starter diff --git a/db/knexfile.ts b/src/db/knexfile.ts similarity index 85% rename from db/knexfile.ts rename to src/db/knexfile.ts index 4aa55bc..c865274 100644 --- a/db/knexfile.ts +++ b/src/db/knexfile.ts @@ -12,10 +12,10 @@ const knexConfig: Knex.Config = { timezone: process.env.DB_TIMEZONE!, }, migrations: { - directory: './migrations', + directory: './dist/db/migrations', }, seeds: { - directory: './seeds', + directory: './dist/db/seeds', }, }; diff --git a/db/migrations/001_settings_migration.ts b/src/db/migrations/001_settings_migration.ts similarity index 100% rename from db/migrations/001_settings_migration.ts rename to src/db/migrations/001_settings_migration.ts diff --git a/db/migrations/002_users_migration.ts b/src/db/migrations/002_users_migration.ts similarity index 100% rename from db/migrations/002_users_migration.ts rename to src/db/migrations/002_users_migration.ts diff --git a/db/migrations/003_api_keys_migration.ts b/src/db/migrations/003_api_keys_migration.ts similarity index 100% rename from db/migrations/003_api_keys_migration.ts rename to src/db/migrations/003_api_keys_migration.ts diff --git a/db/seeds/001_users_seed.ts b/src/db/seeds/001_users_seed.ts similarity index 88% rename from db/seeds/001_users_seed.ts rename to src/db/seeds/001_users_seed.ts index 4494dc7..48c8ea0 100644 --- a/db/seeds/001_users_seed.ts +++ b/src/db/seeds/001_users_seed.ts @@ -1,6 +1,11 @@ import { Knex } from 'knex'; import bcrypt from 'bcrypt'; +/* + This file is used to test the knex seed functionality. + In a production environment, this seed file should not be used. + */ + export async function seed(knex: Knex): Promise { await knex('users').insert([ { diff --git a/src/middleware/authMiddleware.ts b/src/middleware/authMiddleware.ts index 97fd690..cf1598a 100644 --- a/src/middleware/authMiddleware.ts +++ b/src/middleware/authMiddleware.ts @@ -1,9 +1,9 @@ import { NextFunction, Request, Response } from 'express'; import userModel from '../models/userModel'; import { AuthRequest } from '../utils/utils'; -import { mailer } from '../server'; import path from 'path'; import { renderFile } from 'ejs'; +import mailer from '../utils/mailer'; export async function loginUser( req: AuthRequest, diff --git a/src/server.ts b/src/server.ts index e39b41b..de0178a 100644 --- a/src/server.ts +++ b/src/server.ts @@ -4,44 +4,38 @@ import express from 'express'; import fs from 'fs'; import Knex from 'knex'; import path from 'path'; -import knexConfig from '../db/knexfile'; +import knexConfig from './db/knexfile'; import configRouter from './routes/configRoutes'; import sessionRouter from './routes/sessionRoutes'; import userRouter from './routes/userRoutes'; -import nodemailer from 'nodemailer'; -import nodemailerSendGrid from 'nodemailer-sendgrid'; +// Loading environment variables dotenv.config({ path: '../secrets/.env' }); export const db = Knex(knexConfig); +db.migrate.latest().finally(() => { + const app = express(); + const port = parseInt(process.env.PORT as string); -const app = express(); -const port = parseInt(process.env.PORT as string); + app.set('view engine', 'ejs'); -export const mailer = nodemailer.createTransport( - nodemailerSendGrid({ - apiKey: process.env.SENDGRID_API_KEY!, - }), -); + app.use(configRouter); + app.use(sessionRouter); + app.use(userRouter); -app.set('view engine', 'ejs'); + const privateKey = fs.readFileSync( + path.join(__dirname, '..', 'secrets', 'cryptospace.key'), + 'utf8', + ); + const certificate = fs.readFileSync( + path.join(__dirname, '..', 'secrets', 'cryptospace.crt'), + 'utf8', + ); -app.use(configRouter); -app.use(sessionRouter); -app.use(userRouter); + const credentials = { key: privateKey, cert: certificate }; + const httpsServer = https.createServer(credentials, app); -const privateKey = fs.readFileSync( - path.join(__dirname, '..', 'secrets', 'cryptospace.key'), - 'utf8', -); -const certificate = fs.readFileSync( - path.join(__dirname, '..', 'secrets', 'cryptospace.crt'), - 'utf8', -); + httpsServer.listen(port); -const credentials = { key: privateKey, cert: certificate }; -const httpsServer = https.createServer(credentials, app); - -httpsServer.listen(port); - -console.log(`Server is running on port ${port}`); + console.log(`Server is running on port ${port}`); +}); diff --git a/src/utils/mailer.ts b/src/utils/mailer.ts new file mode 100644 index 0000000..fafb486 --- /dev/null +++ b/src/utils/mailer.ts @@ -0,0 +1,8 @@ +import nodemailer from 'nodemailer'; +import nodemailerSendGrid from 'nodemailer-sendgrid'; + +export default nodemailer.createTransport( + nodemailerSendGrid({ + apiKey: process.env.SENDGRID_API_KEY!, + }), +); diff --git a/tsconfig.json b/tsconfig.json index c1754e1..03d5291 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,16 @@ { "compilerOptions": { - "target": "es6", - "module": "commonjs", - "rootDir": "./", - "lib": ["es6"], + "target": "ESNext", + "module": "NodeNext", + "lib": ["ESNext"], + "rootDir": "./src", + "outDir": "./dist", "sourceMap": true, - "outDir": "out", "noEmitOnError": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "strict": true, - "skipLibCheck": true + "strict": true }, - "include": ["src/**/*.ts", "test/**/*.ts", "db/**/*.ts"], + "include": ["src/**/*"], "exclude": ["node_modules"] } diff --git a/views/includes/end.ejs b/views/includes/end.ejs index 3f747f4..43a2dbd 100644 --- a/views/includes/end.ejs +++ b/views/includes/end.ejs @@ -2,7 +2,7 @@