Skip to content

Commit

Permalink
689 save user to database after creating them in Auth0
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Schroer committed Feb 8, 2024
1 parent 67e35a8 commit 76f01dc
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
4 changes: 2 additions & 2 deletions app/pages/Auth/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const LoginPage = () => {
const [modalIsOpen, setModalIsOpen] = useState(false);
const [email, setEmail] = useState("");
const authClient = useAppContext().authClient as WebAuth;
const { passwordlessStart, passwordlessVerify } = AuthService;
const { passwordlessStart, passwordlessLogin } = AuthService;

const logIn = (evt: React.SyntheticEvent) => {
evt.preventDefault();
Expand Down Expand Up @@ -50,7 +50,7 @@ export const LoginPage = () => {
email={email}
modalIsOpen={modalIsOpen}
setModalIsOpen={setModalIsOpen}
verifyCode={(code) => passwordlessVerify(authClient, email, code)}
verifyCode={(code) => passwordlessLogin(authClient, email, code)}
resendCode={() => passwordlessStart(authClient, email)}
buttonText="Log in"
/>
Expand Down
7 changes: 4 additions & 3 deletions app/pages/Auth/SignUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ export const SignUpPage = () => {
const [name, setName] = useState("");
const [organization, setOrganization] = useState("");
const authClient = useAppContext().authClient as WebAuth;
const { passwordlessStart, passwordlessVerify, signUpUser } = AuthService;
const { passwordlessStart, completeUserSignup, initializeUserSignUp } =
AuthService;

const signUp = (evt: React.SyntheticEvent) => {
evt.preventDefault();
signUpUser(authClient, email).then(() => {
initializeUserSignUp(authClient, email).then(() => {
setModalIsOpen(true);
}, (error) => {
if (error.message === 'userExists') {
Expand Down Expand Up @@ -70,7 +71,7 @@ export const SignUpPage = () => {
email={email}
modalIsOpen={modalIsOpen}
setModalIsOpen={setModalIsOpen}
verifyCode={(code) => passwordlessVerify(authClient, email, code)}
verifyCode={(code) => completeUserSignup(authClient, code, email, name, organization)}
resendCode={() => passwordlessStart(authClient, email)}
buttonText="Sign up"
/>
Expand Down
62 changes: 50 additions & 12 deletions app/utils/AuthService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { WebAuth, Auth0Result } from "auth0-js";
import { defaultAuthObject } from "components/AppProvider";
import { get } from "utils/DataService";
import { post } from "utils/DataService";
import type { AuthState } from "components/AppProvider";

/*
Expand Down Expand Up @@ -45,20 +45,42 @@ export default class AuthService {
});
}

static signUpUser = (authClient: WebAuth, email: string) => {
static initializeUserSignUp = (authClient: WebAuth, email: string) => {
return new Promise((resolve, reject) => {
AuthService.userExists(email).then((exists) => {
if (!exists) {
// Todo: save the user's email/name/org to our database along with the ID generated by
// auth0 on successful sign up
resolve(AuthService.passwordlessStart(authClient, email));
} else {
this.userExists(email).then((exists) => {
if (exists) {
reject(new Error('userExists'));
} else {
this.passwordlessStart(authClient, email).then((result) => {
resolve(result);
})
}
});
});
};

// Invokes the passwordlessLogin method and following that saves the user to our database
static completeUserSignup = (authClient: WebAuth,
verificationCode: string,
email: string,
name: string,
organization: (string | null) = null) => {
this.passwordlessLogin(authClient, email, verificationCode);
// We need to optimistically save the user to our database here. The user is saved to the _Auth0_
// database after the passwordlessLogin method succeeds. We also want to save user data in our
// backend. This should be done after a success callback after passwordlessLogin succceds; however,
// the passwordlessLogin success callback does not fire within our app, because, upon success, Auth0
// triggers a redirect to our home page. At that point, we do not have the user's name or organization,
// which we need to save in our database. Thus, we save the user here.
//
// If for some reason, the passwordlessLogin method errors, this code still save the user in our DB.
// At that point, the worst case scenario is that the user will be informed that they have already
// signed up if they try to sign up again and to log in instead. Since the Auth0 passwordless flow
// does not have a sign-up process separate from its log-in process, and thus the user will still
// be created within Auth0 upon going through our site's log-in flow.
this.saveUser(email, name, organization);
};

// This method initiates the sign-in/sign-up process by sending a code
// to the user's inbox.
static passwordlessStart = (authClient: WebAuth, email: string) => {
Expand All @@ -83,11 +105,11 @@ export default class AuthService {

// This method passes the user's verification code to Auth0's server, which
// completes their sign-up/log-in action
static passwordlessVerify = (
static passwordlessLogin = (
authClient: WebAuth,
email: string,
verificationCode: string
) => {
) => {
authClient.passwordlessLogin(
{
connection: "email",
Expand Down Expand Up @@ -133,9 +155,25 @@ export default class AuthService {

static userExists = (email: string) => {
return new Promise((resolve, reject) => {
const response = get(`/api/auth/user_exists?email=${email}`);
post('/api/users/user_exists', {
email
}).then((resp) => {
resp.json().then(result => resolve(result.user_exists));
}, (error) => {
reject(error);
})
});
}

static saveUser = (email: string, name: string, organization: (string | null) = null) => {
return new Promise((resolve, reject) => {
const response = post('/api/users', {
email,
name,
organization,
});
response.then((result) => {
resolve(result.user_exists);
resolve(result);
}, (error) => {
reject(error);
})
Expand Down

0 comments on commit 76f01dc

Please sign in to comment.