diff --git a/bun.lock b/bun.lock index 8736447..9db602c 100644 --- a/bun.lock +++ b/bun.lock @@ -5,15 +5,15 @@ "name": "void.backend", "dependencies": { "@atums/echo": "latest", - "@types/nodemailer": "^6.4.17", "cassandra-driver": "latest", "fast-jwt": "latest", - "nodemailer": "^7.0.3", + "nodemailer": "latest", "pika-id": "latest", }, "devDependencies": { "@biomejs/biome": "latest", "@types/bun": "latest", + "@types/nodemailer": "latest", }, }, }, @@ -21,7 +21,7 @@ "@biomejs/biome", ], "packages": { - "@atums/echo": ["@atums/echo@1.0.6", "", { "dependencies": { "date-fns-tz": "^3.2.0" } }, "sha512-2v0coX0Ptau6pjh4aTJDXMMJ2z/Q+0r8tvLokjeyUnLWGOPMwg+i4saBrkvDtHvQbNiq/NiEwMFLCxeIlxEyLQ=="], + "@atums/echo": ["@atums/echo@1.0.7", "", { "dependencies": { "date-fns-tz": "latest" } }, "sha512-RLHRmAmf/4a4CCGaNJIA1xkgycKBonVoWjyQ5bwW/srLjwhTgxkPbn6o56cRgmRMDguribqv5mWxEol3UL0srg=="], "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], @@ -43,7 +43,7 @@ "@lukeed/ms": ["@lukeed/ms@2.0.2", "", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="], - "@types/bun": ["@types/bun@1.2.15", "", { "dependencies": { "bun-types": "1.2.15" } }, "sha512-U1ljPdBEphF0nw1MIk0hI7kPg7dFdPyM7EenHsp6W5loNHl7zqy6JQf/RKCgnUn2KDzUpkBwHPnEJEjII594bA=="], + "@types/bun": ["@types/bun@1.2.16", "", { "dependencies": { "bun-types": "1.2.16" } }, "sha512-1aCZJ/6nSiViw339RsaNhkNoEloLaPzZhxMOYEa7OzRzO41IGg5n/7I43/ZIAW/c+Q6cT12Vf7fOZOoVIzb5BQ=="], "@types/node": ["@types/node@18.19.111", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-90sGdgA+QLJr1F9X79tQuEut0gEYIfkX9pydI4XGRgvFo9g2JWswefI+WUSUHPYVBHYSEfTEqBxA5hQvAZB3Mw=="], @@ -55,7 +55,7 @@ "bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], - "bun-types": ["bun-types@1.2.15", "", { "dependencies": { "@types/node": "*" } }, "sha512-NarRIaS+iOaQU1JPfyKhZm4AsUOrwUOqRNHY0XxI8GI8jYxiLXLcdjYMG9UKS+fwWasc1uw1htV9AX24dD+p4w=="], + "bun-types": ["bun-types@1.2.16", "", { "dependencies": { "@types/node": "*" } }, "sha512-ciXLrHV4PXax9vHvUrkvun9VPVGOVwbbbBF/Ev1cXz12lyEZMoJpIJABOfPcN9gDJRaiKF9MVbSygLg4NXu3/A=="], "cassandra-driver": ["cassandra-driver@4.8.0", "", { "dependencies": { "@types/node": "^18.11.18", "adm-zip": "~0.5.10", "long": "~5.2.3" } }, "sha512-HritfMGq9V7SuESeSodHvArs0mLuMk7uh+7hQK2lqdvXrvm50aWxb4RPxkK3mPDdsgHjJ427xNRFITMH2ei+Sw=="], diff --git a/package.json b/package.json index 466601d..8fc1362 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ }, "devDependencies": { "@biomejs/biome": "latest", - "@types/bun": "latest" + "@types/bun": "latest", + "@types/nodemailer": "latest" }, "dependencies": { "@atums/echo": "latest", - "@types/nodemailer": "^6.4.17", "cassandra-driver": "latest", "fast-jwt": "latest", - "nodemailer": "^7.0.3", + "nodemailer": "latest", "pika-id": "latest" }, "trustedDependencies": ["@biomejs/biome"] diff --git a/src/environment/constants/index.ts b/src/environment/constants/index.ts index 310a710..6ca789c 100644 --- a/src/environment/constants/index.ts +++ b/src/environment/constants/index.ts @@ -31,3 +31,4 @@ export * from "./server"; export * from "./validation"; export * from "./database"; export * from "./mailer"; +export * from "./user"; diff --git a/src/environment/constants/user/index.ts b/src/environment/constants/user/index.ts new file mode 100644 index 0000000..635be64 --- /dev/null +++ b/src/environment/constants/user/index.ts @@ -0,0 +1 @@ +export * from "./update"; diff --git a/src/environment/constants/user/update.ts b/src/environment/constants/user/update.ts new file mode 100644 index 0000000..f69fe57 --- /dev/null +++ b/src/environment/constants/user/update.ts @@ -0,0 +1,6 @@ +const emailUpdateTimes = { + coolDownMinutes: 5, + tokenExpiryHours: 3, +}; + +export { emailUpdateTimes }; diff --git a/src/environment/mailer/templates/email-change-completed-notification.html b/src/environment/mailer/templates/email-change-completed-notification.html new file mode 100644 index 0000000..87cb9c4 --- /dev/null +++ b/src/environment/mailer/templates/email-change-completed-notification.html @@ -0,0 +1,40 @@ + + +
+ + +Hi {{displayName}},
+Your email address has been successfully changed.
+ +Change Details:
+Previous Email: {{oldEmail}} (this address)
+ New Email: {{newEmail}}
+ Changed On: {{changeTime}}
Important: You will no longer receive account emails at this address ({{oldEmail}}). All future communications will be sent to {{newEmail}}.
+ +For future logins, please use:
+Email: {{newEmail}}
+ Password: (unchanged)
If this change was not authorized by you: Contact our support team immediately at {{supportEmail}}. Your account may have been compromised and we will help you recover it.
+User ID: {{id}} | {{companyName}}
+ + diff --git a/src/environment/mailer/templates/email-change-request-notification.html b/src/environment/mailer/templates/email-change-request-notification.html new file mode 100644 index 0000000..5d7216b --- /dev/null +++ b/src/environment/mailer/templates/email-change-request-notification.html @@ -0,0 +1,41 @@ + + + + + +Hi {{displayName}},
+Security Notice: Someone requested to change your account email address.
+ +Change Details:
+Current Email: {{currentEmail}}
+ Requested New Email: {{newEmail}}
+ Request Time: {{requestTime}}
A verification email has been sent to {{newEmail}}.
+{{willExpire}} if not completed.
+ +If this was you: Check your new email ({{newEmail}}) and click the verification link to complete the change.
+ +If this was NOT you: Your account may be compromised. Please change your password immediately and contact our support team at {{supportEmail}}.
+ +Questions? Contact {{supportEmail}}
+User ID: {{id}} | {{companyName}}
+ + diff --git a/src/environment/mailer/templates/email-change-verification.html b/src/environment/mailer/templates/email-change-verification.html new file mode 100644 index 0000000..61e43c2 --- /dev/null +++ b/src/environment/mailer/templates/email-change-verification.html @@ -0,0 +1,41 @@ + + + + + +Hi {{displayName}},
+You requested to change your email address from {{currentEmail}} to {{newEmail}}.
+To complete this email change, please click the button below:
+ + Verify Email Change + +{{willExpire}} for security reasons.
+Important: After verification, your account email will be changed to this address and you'll need to use it for future logins.
+If you did not request this email change, contact {{supportEmail}} immediately.
+Questions? Contact {{supportEmail}}
+User ID: {{id}} | {{companyName}}
+ + diff --git a/src/environment/mailer/templates/forgot-password.html b/src/environment/mailer/templates/forgot-password.html index b018ef5..03d682d 100644 --- a/src/environment/mailer/templates/forgot-password.html +++ b/src/environment/mailer/templates/forgot-password.html @@ -1,6 +1,5 @@ - @@ -13,35 +12,28 @@ padding: 20px; line-height: 1.5; } - - a { - color: #0066cc; + .reset-button { + display: inline-block; + background-color: #0066cc; + color: white; + padding: 10px 20px; + text-decoration: none; + border-radius: 3px; + margin: 15px 0; } -Hi {{displayName}},
+You requested a password reset for your account. Click the button below to reset your password:
-You requested a password reset for your account. Click the link below to reset your password:
- - + Reset Password{{willExpire}} for security reasons.
- -If you did not request this password reset, please ignore this email. Your password will remain unchanged.
- +If you did not request this password reset, please contact {{supportEmail}} immediately. Your password will remain unchanged.
Questions? Contact {{supportEmail}}
- -Best regards,
- The {{companyName}} team
User ID: {{id}} | © {{currentYear}} {{companyName}}
- +User ID: {{id}} | {{companyName}}
- - \ No newline at end of file +