From f4a156b583807276910ff709ec3fa3688b9f5fb0 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Tue, 11 Mar 2025 14:14:58 -0700 Subject: [PATCH] feat: move from matrix to email notifs --- package.json | 5 +- pnpm-lock.yaml | 172 +++++----------------------------------- prod.env | 3 +- src/index.ts | 33 +------- src/modules/sendMail.ts | 36 +++++++++ src/server/serve.ts | 57 +++---------- 6 files changed, 71 insertions(+), 235 deletions(-) create mode 100644 src/modules/sendMail.ts diff --git a/package.json b/package.json index 2a0c92a..536e3c6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alert-server", "version": "1.0.0", - "description": "A web server that sends alerts to our Matrix room.", + "description": "A web server that sends alerts to our logging inbox.", "main": "index.js", "type": "module", "scripts": { @@ -17,11 +17,12 @@ "@nhcarrigan/eslint-config": "5.1.0", "@nhcarrigan/typescript-config": "4.0.0", "@types/node": "22.13.1", + "@types/nodemailer": "6.4.17", "eslint": "9.20.0", "typescript": "5.7.3" }, "dependencies": { "fastify": "5.2.1", - "matrix-js-sdk": "36.1.0" + "nodemailer": "6.10.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f79aaee..b3a63c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,9 @@ importers: fastify: specifier: 5.2.1 version: 5.2.1 - matrix-js-sdk: - specifier: 36.1.0 - version: 36.1.0 + nodemailer: + specifier: 6.10.0 + version: 6.10.0 devDependencies: '@nhcarrigan/eslint-config': specifier: 5.1.0 @@ -24,6 +24,9 @@ importers: '@types/node': specifier: 22.13.1 version: 22.13.1 + '@types/nodemailer': + specifier: 6.4.17 + version: 6.4.17 eslint: specifier: 9.20.0 version: 9.20.0 @@ -41,10 +44,6 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.26.7': - resolution: {integrity: sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==} - engines: {node: '>=6.9.0'} - '@es-joy/jsdoccomment@0.49.0': resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} engines: {node: '>=16'} @@ -297,13 +296,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@matrix-org/matrix-sdk-crypto-wasm@12.1.0': - resolution: {integrity: sha512-NhJFu/8FOGjnW7mDssRUzaMSwXrYOcCqgAjZyAw9KQ9unNADKEi7KoIKe7GtrG2PWtm36y2bUf+hB8vhSY6Wdw==} - engines: {node: '>= 18'} - - '@matrix-org/olm@3.2.15': - resolution: {integrity: sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q==} - '@nhcarrigan/eslint-config@5.1.0': resolution: {integrity: sha512-TS6kwPTcm8pFzp34FRq+8PR+0jgVr7FDUDrfilAKtWDArqZSabTMtTt+N1rJyNHQqBHs7de/pUYNWiLpThy2Bw==} engines: {node: '>=22', pnpm: '>=9'} @@ -443,9 +435,6 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/events@3.0.3': - resolution: {integrity: sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -455,12 +444,12 @@ packages: '@types/node@22.13.1': resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==} + '@types/nodemailer@6.4.17': + resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/retry@0.12.0': - resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} - '@typescript-eslint/eslint-plugin@8.19.0': resolution: {integrity: sha512-NggSaEZCdSrFddbctrVjkVZvFC6KGfKfNK0CU7mNK/iKHGKbzT4Wmgm08dKpcZECBu9f5FypndoMyRHkdqfT1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -634,9 +623,6 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - another-json@0.2.0: - resolution: {integrity: sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg==} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -706,9 +692,6 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base-x@5.0.0: - resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -724,9 +707,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - bs58@6.0.0: - resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} - builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -788,10 +768,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} @@ -1041,10 +1017,6 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - expect-type@1.1.0: resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} engines: {node: '>=12.0.0'} @@ -1395,10 +1367,6 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} - jwt-decode@4.0.0: - resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} - engines: {node: '>=18'} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1423,10 +1391,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - loglevel@1.9.2: - resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} - engines: {node: '>= 0.6.0'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1441,16 +1405,6 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - matrix-events-sdk@0.0.1: - resolution: {integrity: sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==} - - matrix-js-sdk@36.1.0: - resolution: {integrity: sha512-KNPswMSAGKDxBybJedxRpWadaRes9paxmjTCUsQT8t1Jg3ZENraAt6ynIaxh6PxazAH9D5ly6EYKHaLMLbZ1Dg==} - engines: {node: '>=20.0.0'} - - matrix-widget-api@1.13.1: - resolution: {integrity: sha512-mkOHUVzaN018TCbObfGOSaMW2GoUxOfcxNNlTVx5/HeMk3OSQPQM0C9oEME5Liiv/dBUoSrEB64V8wF7e/gb1w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1487,6 +1441,10 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nodemailer@6.10.0: + resolution: {integrity: sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==} + engines: {node: '>=6.0.0'} + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -1522,10 +1480,6 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - oidc-client-ts@3.1.0: - resolution: {integrity: sha512-IDopEXjiwjkmJLYZo6BTlvwOtnlSniWZkKZoXforC/oLZHC9wkIxd25Kwtmo5yKFMMVcsp3JY6bhcNJqdYk8+g==} - engines: {node: '>=18'} - on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -1554,10 +1508,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-retry@4.6.2: - resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} - engines: {node: '>=8'} - p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1682,9 +1632,6 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true @@ -1722,10 +1669,6 @@ packages: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} - retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1760,10 +1703,6 @@ packages: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} - sdp-transform@2.15.0: - resolution: {integrity: sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==} - hasBin: true - secure-json-parse@3.0.2: resolution: {integrity: sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==} @@ -1995,9 +1934,6 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - unhomoglyph@1.0.6: - resolution: {integrity: sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg==} - update-browserslist-db@1.1.2: resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} hasBin: true @@ -2007,10 +1943,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - uuid@11.0.5: - resolution: {integrity: sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==} - hasBin: true - validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -2131,10 +2063,6 @@ snapshots: '@babel/helper-validator-identifier@7.25.9': {} - '@babel/runtime@7.26.7': - dependencies: - regenerator-runtime: 0.14.1 - '@es-joy/jsdoccomment@0.49.0': dependencies: comment-parser: 1.4.1 @@ -2312,10 +2240,6 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} - '@matrix-org/matrix-sdk-crypto-wasm@12.1.0': {} - - '@matrix-org/olm@3.2.15': {} - '@nhcarrigan/eslint-config@5.1.0(@typescript-eslint/utils@8.24.0(eslint@9.20.0)(typescript@5.7.3))(eslint@9.20.0)(playwright@1.50.1)(react@19.0.0)(typescript@5.7.3)(vitest@3.0.5(@types/node@22.13.1))': dependencies: '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.20.0) @@ -2436,8 +2360,6 @@ snapshots: '@types/estree@1.0.6': {} - '@types/events@3.0.3': {} - '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -2446,9 +2368,11 @@ snapshots: dependencies: undici-types: 6.20.0 - '@types/normalize-package-data@2.4.4': {} + '@types/nodemailer@6.4.17': + dependencies: + '@types/node': 22.13.1 - '@types/retry@0.12.0': {} + '@types/normalize-package-data@2.4.4': {} '@typescript-eslint/eslint-plugin@8.19.0(@typescript-eslint/parser@8.19.0(eslint@9.20.0)(typescript@5.7.3))(eslint@9.20.0)(typescript@5.7.3)': dependencies: @@ -2682,8 +2606,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - another-json@0.2.0: {} - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -2775,8 +2697,6 @@ snapshots: balanced-match@1.0.2: {} - base-x@5.0.0: {} - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -2797,10 +2717,6 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.2(browserslist@4.24.4) - bs58@6.0.0: - dependencies: - base-x: 5.0.0 - builtin-modules@3.3.0: {} cac@6.7.14: {} @@ -2857,8 +2773,6 @@ snapshots: concat-map@0.0.1: {} - content-type@1.0.5: {} - cookie@1.0.2: {} core-js-compat@3.40.0: @@ -3275,8 +3189,6 @@ snapshots: esutils@2.0.3: {} - events@3.3.0: {} - expect-type@1.1.0: {} fast-decode-uri-component@1.0.1: {} @@ -3650,8 +3562,6 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 - jwt-decode@4.0.0: {} - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3679,8 +3589,6 @@ snapshots: lodash.merge@4.6.2: {} - loglevel@1.9.2: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3693,31 +3601,6 @@ snapshots: math-intrinsics@1.1.0: {} - matrix-events-sdk@0.0.1: {} - - matrix-js-sdk@36.1.0: - dependencies: - '@babel/runtime': 7.26.7 - '@matrix-org/matrix-sdk-crypto-wasm': 12.1.0 - '@matrix-org/olm': 3.2.15 - another-json: 0.2.0 - bs58: 6.0.0 - content-type: 1.0.5 - jwt-decode: 4.0.0 - loglevel: 1.9.2 - matrix-events-sdk: 0.0.1 - matrix-widget-api: 1.13.1 - oidc-client-ts: 3.1.0 - p-retry: 4.6.2 - sdp-transform: 2.15.0 - unhomoglyph: 1.0.6 - uuid: 11.0.5 - - matrix-widget-api@1.13.1: - dependencies: - '@types/events': 3.0.3 - events: 3.3.0 - merge2@1.4.1: {} micromatch@4.0.8: @@ -3745,6 +3628,8 @@ snapshots: node-releases@2.0.19: {} + nodemailer@6.10.0: {} + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -3793,10 +3678,6 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - oidc-client-ts@3.1.0: - dependencies: - jwt-decode: 4.0.0 - on-exit-leak-free@2.1.2: {} optionator@0.9.4: @@ -3830,11 +3711,6 @@ snapshots: dependencies: p-limit: 3.1.0 - p-retry@4.6.2: - dependencies: - '@types/retry': 0.12.0 - retry: 0.13.1 - p-try@2.2.0: {} parent-module@1.0.1: @@ -3955,8 +3831,6 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerator-runtime@0.14.1: {} - regexp-tree@0.1.27: {} regexp.prototype.flags@1.5.4: @@ -3992,8 +3866,6 @@ snapshots: ret@0.5.0: {} - retry@0.13.1: {} - reusify@1.0.4: {} rfdc@1.4.1: {} @@ -4052,8 +3924,6 @@ snapshots: safe-stable-stringify@2.5.0: {} - sdp-transform@2.15.0: {} - secure-json-parse@3.0.2: {} semver@5.7.2: {} @@ -4311,8 +4181,6 @@ snapshots: undici-types@6.20.0: {} - unhomoglyph@1.0.6: {} - update-browserslist-db@1.1.2(browserslist@4.24.4): dependencies: browserslist: 4.24.4 @@ -4323,8 +4191,6 @@ snapshots: dependencies: punycode: 2.3.1 - uuid@11.0.5: {} - validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 diff --git a/prod.env b/prod.env index 6255869..40d9791 100644 --- a/prod.env +++ b/prod.env @@ -1,3 +1,4 @@ MATRIX_ACCESS_TOKEN="op://Environment Variables - Naomi/Alert Server/matrix_access_token" MATRIX_ROOM_ID="op://Environment Variables - Naomi/Alert Server/matrix_room_id" -API_AUTH="op://Environment Variables - Naomi/Alert Server/api_auth" \ No newline at end of file +API_AUTH="op://Environment Variables - Naomi/Alert Server/api_auth" +EMAIL_PASSWORD="op://Environment Variables - Naomi/Alert Server/email_pass" \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 21c12ba..869e01a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,37 +4,6 @@ * @author Naomi Carrigan */ -import { createClient } from "matrix-js-sdk"; import { instantiateServer } from "./server/serve.js"; -import type { Logger } from "matrix-js-sdk/lib/logger.js"; -const logger: Logger = { - debug: () => { - return null; - }, - error: () => { - return null; - }, - getChild: () => { - return logger; - }, - info: () => { - return null; - }, - trace: () => { - return null; - }, - warn: () => { - return null; - }, -}; - -const client = createClient({ - accessToken: process.env.MATRIX_ACCESS_TOKEN ?? "", - baseUrl: "https://matrix.nhcarrigan.com", - logger: logger, - userId: "@alerts:matrix.nhcarrigan.com", -}); - -await client.startClient({ initialSyncLimit: 10 }); -instantiateServer(client); +instantiateServer(); diff --git a/src/modules/sendMail.ts b/src/modules/sendMail.ts new file mode 100644 index 0000000..3c7e1c9 --- /dev/null +++ b/src/modules/sendMail.ts @@ -0,0 +1,36 @@ +/** + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ +import { createTransport } from "nodemailer"; +// eslint-disable-next-line @typescript-eslint/naming-convention -- This is a type import. +import type SMTPTransport from "nodemailer/lib/smtp-transport/index.js"; + +/** + * Sends an email. + * @param subject - The subject of the email. + * @param body - The text content of the email. + */ +export const sendMail = async(subject: string, body: string): Promise => { + const options: SMTPTransport["options"] = { + auth: { + pass: process.env.EMAIL_PASSWORD ?? "", + type: "login", + user: "noreply@nhcarrigan.com", + }, + host: "mail.nhcarrigan.com", + port: 465, + secure: true, + }; + const defaults: SMTPTransport["options"] = { + from: "noreply@nhcarrigan.com", + to: "logs@nhcarrigan.com", + }; + const transport = createTransport(options, defaults); + + await transport.sendMail({ + subject: subject, + text: body, + }); +}; diff --git a/src/server/serve.ts b/src/server/serve.ts index e18c543..8a2d2dc 100644 --- a/src/server/serve.ts +++ b/src/server/serve.ts @@ -5,8 +5,8 @@ */ import fastify from "fastify"; -import { MsgType, type MatrixClient } from "matrix-js-sdk"; import { auth } from "../modules/auth.js"; +import { sendMail } from "../modules/sendMail.js"; import { errorSchema } from "../schemas/errorSchema.js"; import { logSchema } from "../schemas/logSchema.js"; import { uptimeSchema } from "../schemas/uptimeSchema.js"; @@ -20,14 +20,14 @@ const html = ` Rosalia Nightsong - +

Rosalia Nightsong

-

A basic web server and Matrix bot that allows us to pipe logs and errors from our applications into a Matrix room.

+

A basic web server that allows us to pipe logs and errors from our applications into our inbox.

Links

@@ -53,10 +53,9 @@ const html = ` /** * Starts up the server to receive events. - * @param client - The authenticated Matrix client. */ // eslint-disable-next-line max-lines-per-function -- This function is long because it is setting up a server. -export const instantiateServer = (client: MatrixClient): void => { +export const instantiateServer = (): void => { try { const server = fastify({ logger: false, @@ -74,13 +73,7 @@ export const instantiateServer = (client: MatrixClient): void => { return; } const { application, level, message } = request.body; - await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `**${application}** - *${level}*\n${message}`, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${application} - ${level}
${message}`, - msgtype: MsgType.Text, - }); + await sendMail(`[${level}]: ${application}`, message); await response.status(200).send({ success: true }); }); @@ -94,13 +87,7 @@ export const instantiateServer = (client: MatrixClient): void => { return; } const { application, context, stack, message } = request.body; - await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack}\n\`\`\``, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${application} - Error in ${context}
${message}
${stack}`, - msgtype: MsgType.Text, - }); + await sendMail(`[ERROR]: ${context} - ${application}`, `${message}\n\n${stack}`); await response.status(200).send({ success: true }); }, ); @@ -115,13 +102,7 @@ export const instantiateServer = (client: MatrixClient): void => { return; } const { application, message } = request.body; - await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `${message}\n${application}`, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${message}
${application}`, - msgtype: MsgType.Text, - }); + await sendMail(`[UPTIME]: ${application}`, message); await response.status(200).send({ success: true }); }, ); @@ -131,36 +112,18 @@ export const instantiateServer = (client: MatrixClient): void => { if (error) { const { message, stack } = error; const context = "Server Startup"; - void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack ?? "No stack trace available."}\n\`\`\``, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${application} - Error in ${context}
${message}
${stack ?? "No stack trace available."}`, - msgtype: MsgType.Text, - }); + void sendMail(`[ERROR]: ${context} - ${application}`, `${message}\n\n${String(stack)}`); return; } const level = "debug"; const message = `Server listening on port 5003.`; - void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `**${application}** - *${level}*\n${message}`, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${application} - ${level}
${message}`, - msgtype: MsgType.Text, - }); + void sendMail(`[${level}]: ${application}`, message); }); } catch (error) { const application = "Alert Server"; const context = "Server Startup"; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Totally being lazy. const { message, stack } = error as Error; - void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { - body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack}\n\`\`\``, - format: "org.matrix.custom.html", - // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. - formatted_body: `${application} - Error in ${context}
${message}
${stack}`, - msgtype: MsgType.Text, - }); + void sendMail(`[ERROR]: ${context} - ${application}`, `${message}\n\n${stack}`); } }; -- 2.47.2