-
-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sendVerificationEmail and setup email #59
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR looks good, I think you should implement the verify-email route as well for the PR to be complete.
if (!address || !includes(user.emails.map((email: string) => email.address), address)) { | ||
throw new AccountsError('No such email address for user'); | ||
} | ||
const token = await this.db.addEmailVerificationToken(userId, address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The db should layer should probably not be responsible of creating the token as this will be the same logic for every store. The only caveat with moving that logic to here is that the token should be unique and so we need the db to allow search by email verification token to make sure the "new token" is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now there is this function that generate the token https://github.com/js-accounts/accounts/blob/master/packages/server/src/tokens.js#L5 and in verifyEmail function there is this call to the bdd (who must take the token as parameter btw) to find the user with the token
throw new AccountsError('No such email address for user'); | ||
} | ||
const token = await this.db.addEmailVerificationToken(userId, address); | ||
const resetPasswordUrl = `${this._options.siteUrl}/reset-password/${token}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this has reset-password route?
@davidyaha Now the token is generated in the function, is it better? |
@@ -302,6 +321,57 @@ export class AccountsServer { | |||
const res = await this.db.setProfile(userId, { ...user.profile, ...profile }); | |||
return res; | |||
} | |||
|
|||
async sendVerificationEmail(userId: string, address: string): Promise<void> { | |||
const user = await this.db.findUserById(userId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably extract the code from this line to L338 to another function because it is repeating on the sendResetPasswordEmail
method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not exactly the same things for sendVerificationEmail
this will return the first unverified email.
For sendResetPasswordEmail
it will return the first email.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Will you be adding the checks for expired tokens in this PR or are those todos for the future?
const emailRecord = find(user.emails, (e: Object) => e.address === tokenRecord.address); | ||
if (!emailRecord) { | ||
throw new AccountsError('Verify email link is for unknown address'); | ||
} | ||
await this.db.verifyEmail(user.id, emailRecord); | ||
} | ||
|
||
async resetPassword(token: string, newPassword: string): Promise<void> { | ||
const user = await this.db.findUserByResetPasswordToken(token); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be named findByResetPasswordToken
. For example theres no "User" in the findByEmail
name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All our find are with User
even findUserByEmail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops nevermind then 😄
packages/server/src/email.js
Outdated
|
||
sendMail(mail: Object): Promise<Object> { | ||
return new Promise((resolve, reject) => { // eslint-disable-line flowtype/require-parameter-type | ||
// If no configuration for email just warm the user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, "warn" not "warm"
resolve(); | ||
return; | ||
} | ||
this.server.send(mail, (err: Object, message: Object) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be cool if user could set a function in the config to handle sending emails. At the moment I think this only supports smtp, but what about the use case when you want to do an api call to mailgun to send the email?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good idea 👍
@TimMikeladze If you can review the README |
@pradel Looks good |
#40
Setup email part.
Add siteUrl in config to construct absolute urls for email.
Add sendVerificationEmail.
Add sendResetPasswordEmail.
To overwrite the email templates: