# How is auth done?

You will notice that in the facebook.ts and google.ts files, the auth is handled in a slightly more complicated way, with 2 passport strategies each.

This is to ensure that a user checks the terms of service and privacy policy before they can use the app.

### The Social Login Strategy

Both strategies work in a similar fashion, so we will only look at the facebook strategy.

`GET /auth/facebook`
This sets the session variable `auth_type` to `login` and redirects the user to the facebook login page.

> In this flow, the token will not be issued if they don't already have an account.

`GET /auth/facebook/signup`
This sets the session variable `auth_type` to `signup` and redirects the user to the facebook login page.

`GET /oauth2/redirect/facebook`
This is the callback url that facebook redirects to after the user has logged in to Facebook. We can only define a single redirect for both strategies, which is why we set the session variable before. It will check the session variable to see which method to call and call the appriopriate method.

`function runLoginAuthProvider`
This function is called on the login endpoints. It will check the database to see if the user already exists, and if so they will be logged in. If not, they will be redirected to the signup page.

`function runAuthProvider`
// TODO: no longer accurate
This is the original function that handled both logins and signups. It will check the database to see if the user already exists, and if so they will be logged in. If not, a new user will be created and then they will be logged in. If they hit this endpoint, we will assume that they have already agreed to the terms of service and privacy policy.

**Conclusion**
As you can see, the user is only created if they hit the signup endpoint. And they will only be able to do that if they're accessing the signup modal on the frontend.

### The Email Login Strategy

This strategy is much simpler, all the logic is handled in the `fusionauth.ts` file.
Password storage and forgot password flows are handled by FusionAuth.

In order to log in via email, you will need to forward the port to provide access to fusionauth locally. Run the `scripts/forward_prod.sh` script to do this.

> The token will not be issued if they don't already have an account, and have verified their email.

`POST /auth/email/login`
This endpoint will check the database to see if the user exists, and if they are verified, they will be logged in. If not, they will be given the option to resend the verification email.

`POST /auth/email/register`
This endpoint will check the database to see if the user exists, it will return an error if so. If not, a new user will be created on fusionauth and a verification email will be sent to the user.

`POST /auth/email/verify`
If the verification is successful, the user will be logged in. This only works on the most recent verification that hasn't expired. If the user is already verified, this will also return an error.

`POST /auth/email/resend-verification`
This will resend the verification email to the user if the user is not already verified. It will not return an error to prevent email enumeration.

`POST /auth/email/forgot`
This endpoint will send a forgot password email to the user. It does not need verification to work.

`POST /auth/email/reset-password`
This endpoint will reset the user's password if the forgot password code is correct. It does not need verification to work.
