-
-
Notifications
You must be signed in to change notification settings - Fork 38
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
feat: verify email #249
base: master
Are you sure you want to change the base?
feat: verify email #249
Changes from 9 commits
72d220d
7fb4cfc
298ab9f
9203287
2e51633
d309b96
3d94d62
bc67ded
01513cc
a400f43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<div style="text-align: center; font-size: 18px"> | ||
<table width="100%"> | ||
<tbody> | ||
<tr> | ||
<td align="center"> | ||
<img | ||
style="width: 39%; max-width: 234px" | ||
src="http://cdn.mcauto-images-production.sendgrid.net/83a8af126d5ca8ff/70fa68eb-a954-47c6-9798-306089b6a4e3/600x370.jpg" | ||
alt="Illustration" | ||
/> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
<h2 style="font-size: 26px; font-weight: normal">Hey <%= name %></h2> | ||
<h1 | ||
style=" | ||
font-size: 32px; | ||
line-height: 42px; | ||
font-weight: normal; | ||
color: #69d5b1; | ||
" | ||
> | ||
You're almost there! | ||
</h1> | ||
<p>Please click the link below to verify your email</p> | ||
<p style="margin-top: 10px"> | ||
<a | ||
href="https://mentors.codingcoach.io/me" | ||
style=" | ||
background-color: #00bc89; | ||
border: 1px solid #333333; | ||
border-color: #00bc89; | ||
border-radius: 6px; | ||
border-width: 1px; | ||
color: #ffffff; | ||
display: inline-block; | ||
font-size: 16px; | ||
font-weight: normal; | ||
letter-spacing: 0px; | ||
line-height: 16px; | ||
padding: 12px 18px 12px 18px; | ||
text-align: center; | ||
text-decoration: none; | ||
" | ||
target="_blank" | ||
>Verify</a | ||
> | ||
</p> | ||
<p style="margin-top: 10px"> | ||
<small> | ||
(Or copy and paste this url | ||
<a herf="<%= link %>" target="_blank"><%= link %></a> into your browser) | ||
</p> | ||
</div> |
Large diffs are not rendered by default.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { HttpException, Injectable } from '@nestjs/common'; | ||
import fetch from 'node-fetch'; | ||
import * as Sentry from '@sentry/node'; | ||
import Config from '../../../config'; | ||
import type { Auth0Response, EmailVerificationTicket } from './auth0.types'; | ||
|
||
@Injectable() | ||
export class Auth0Service { | ||
// Get an access token for the Auth0 Admin API | ||
async getAdminAccessToken(): Promise<{ access_token: string }> { | ||
const options = { | ||
method: 'POST', | ||
headers: { 'content-type': 'application/json' }, | ||
body: JSON.stringify({ | ||
client_id: Config.auth0.backend.CLIENT_ID, | ||
client_secret: Config.auth0.backend.CLIENT_SECRET, | ||
audience: `https://${Config.auth0.backend.DOMAIN}/api/v2/`, | ||
grant_type: 'client_credentials', | ||
}), | ||
}; | ||
|
||
const response = await fetch( | ||
`https://${Config.auth0.backend.DOMAIN}/oauth/token`, | ||
options, | ||
); | ||
const json = await response.json(); | ||
|
||
return json; | ||
} | ||
|
||
// Get the user's profile from auth0 | ||
async getUserProfile(accessToken: string, userID: string) { | ||
const options = { | ||
headers: { | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
}; | ||
|
||
const response = await fetch( | ||
`https://${Config.auth0.backend.DOMAIN}/api/v2/users/${userID}`, | ||
options, | ||
); | ||
const json = await response.json(); | ||
|
||
return json; | ||
} | ||
|
||
// Deletes a user from auth0 | ||
async deleteUser(accessToken: string, userID: string) { | ||
const options = { | ||
method: 'DELETE', | ||
headers: { | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
}; | ||
|
||
const response = await fetch( | ||
`https://${Config.auth0.backend.DOMAIN}/api/v2/users/${userID}`, | ||
options, | ||
); | ||
|
||
return response; | ||
} | ||
|
||
async createVerificationEmailTicket( | ||
accessToken: string, | ||
auth0UserId: string, | ||
) { | ||
try { | ||
const [provider, userId] = auth0UserId.split('|'); | ||
const payload = { | ||
result_url: Config.urls.CLIENT_BASE_URL, | ||
user_id: auth0UserId, | ||
identity: { user_id: userId, provider }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiousity, why are you stripping of the first part of the userId? It looks like you refer to userId as the part behind the Looking at https://auth0.com/docs/manage-users/user-accounts/identify-users, it seems to be that we guarantee the userId to be unique in a tenant (which means, including the part before the That said, I am not entirely sure here. But if u don't need to strip it, I wouldn't strip it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First, this is what works for me :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just wanted to call it out that you are aware. Not asking to change anything. The most important part is that it works for u, just as I mentioned ... If u don't need the stripping, I wouldn't do it. But if u need it, u need it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes but the prefix is part of the userId for us. So seeing it stripped of while still referring to it as a userId can be confusing if you are used to Auth0 UserId's. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you saying I should use the full userid or should I name it differently? If 2, any suggestion? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you saying I should use the full userid or should I name it differently? If 2, any suggestion? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think as long as you are aware of the importance of the provider, you should be fine either way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! |
||
}; | ||
|
||
const options = { | ||
method: 'POST', | ||
headers: { | ||
/* tslint:disable-next-line */ | ||
Authorization: `Bearer ${accessToken}`, | ||
'content-type': 'application/json', | ||
}, | ||
body: JSON.stringify(payload), | ||
}; | ||
|
||
const response: Auth0Response<EmailVerificationTicket> = await ( | ||
await fetch( | ||
`https://${Config.auth0.backend.DOMAIN}/api/v2/tickets/email-verification`, | ||
options, | ||
) | ||
).json(); | ||
|
||
if ('statusCode' in response) { | ||
throw new HttpException(response, response.statusCode); | ||
} | ||
|
||
return response; | ||
} catch (error) { | ||
Sentry.captureException(error); | ||
throw error; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
type Auth0ResponseSuccess<T> = T; | ||
|
||
export interface EmailVerificationTicket { | ||
ticket: string; | ||
} | ||
|
||
interface Auth0ResponseError { | ||
statusCode: number; | ||
error: string; | ||
message: string; | ||
errorCode: string; | ||
} | ||
|
||
export type Auth0Response<T = any> = | ||
| Auth0ResponseSuccess<T> | ||
| Auth0ResponseError; | ||
|
||
interface Auth0UserIdentity { | ||
connection: string; | ||
provider: string; | ||
user_id: string; | ||
isSocial: boolean; | ||
} | ||
|
||
export interface Auth0User { | ||
created_at: string; | ||
email: string; | ||
email_verified: boolean; | ||
identities: Auth0UserIdentity[]; | ||
name: string; | ||
nickname: string; | ||
picture: string; | ||
updated_at: string; | ||
user_id: string; | ||
last_ip: string; | ||
last_login: string; | ||
logins_count: number; | ||
} |
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.
lol, what's with the 🧙♂️ in the filepath?
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.
I was exciting to use tsconfig/paths for the first time :)
find-a-mentor-api/tsconfig.json
Lines 14 to 16 in bc67ded
🧙♂️ is our
paths
root