Skip to content

Commit

Permalink
Merge branch 'accountCreation' of https://github.com/swat-sccs/sauce
Browse files Browse the repository at this point in the history
…into accountCreation
  • Loading branch information
adic2023 committed Oct 8, 2023
2 parents a3ca740 + adf1bd0 commit 3e173aa
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 18 deletions.
9 changes: 5 additions & 4 deletions src/controllers/accountController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,21 @@ export const verifyEmail = async (creds: ResetCredentials): Promise<VerifyEmailR
'This email verification link is invalid or expired. <a href="/account/create">Request a new one</a>.',
};

const resetRequest = await VerifyEmailRequestModel.findById(creds.id);
if (!resetRequest) {
const verifyRequest = await VerifyEmailRequestModel.findById(creds.id);
if (!verifyRequest) {
throw new HttpException(400, {
...invalidProps,
message: `Email verification ID ${creds.id} did not match any request`,
});
}

if (!(await argon2.verify(resetRequest.key, creds.key as string))) {
if (!(await argon2.verify(verifyRequest.key, creds.key as string))) {
throw new HttpException(400, {
...invalidProps,
message: 'Email verification key did not match database',
});
}
return resetRequest;
return verifyRequest;
};

export const doPasswordReset = async (params: PasswordResetRequestParams) => {
Expand Down Expand Up @@ -280,6 +280,7 @@ export const isEmailAvailable = async (email: string): Promise<boolean> => {
const [inDatabase, inPending] = await Promise.all([
searchAsync(ldapClient, ldapEscape.filter`(swatmail=${email})`),
TaskModel.exists({ 'data.email': email, status: 'pending' }),
VerifyEmailRequestModel.exists({ 'data.email': email }),
]);

if (inDatabase || inPending) {
Expand Down
5 changes: 0 additions & 5 deletions src/functions/createAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,4 @@ export const createAccount = async (data: any) => {
subject: 'Verify your SCCS account',
html: emailText,
});

const msgUrl = nodemailer.getTestMessageUrl(info);
if (msgUrl) {
logger.debug(`View message at ${msgUrl}`);
}
};
7 changes: 3 additions & 4 deletions src/integration/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,12 @@ export const PasswordResetRequestModel = mongoose.model<PasswordResetRequest>(
export interface VerifyEmailRequest {
// verification email links generate two keys: the ID, which is stored plain, and the key, which is
// hashed with argon2 before being stored.
// good chance the rest of this shit is wrong in this implementation:
// Both are provided to the user and they make a request;
// then we look up the request for the ID and compare hashed keys, basically exactly like a normal
// username/password login flow.
_id: string;
key: string;
user: string;
email: string;
timestamp: Date;
suppressEmail?: boolean;
}
Expand All @@ -108,10 +107,10 @@ const verifyEmailRequestSchema = new mongoose.Schema<VerifyEmailRequest>({
type: String,
required: true,
},
user: {
email: {
type: String,
required: true,
index: true, // we'll search by user to invalidate previous reset requests
index: true,
},
timestamp: {
type: Date,
Expand Down
8 changes: 4 additions & 4 deletions src/routes/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ router.get(
}),
);

router.get(
router.post(
'/init',
catchErrors(async (req, res, next) => {
const { error, value } = jf.validateAsClass(req.query, controller.ResetCredentials);
Expand All @@ -109,14 +109,14 @@ router.get(
}

// I have no idea why joiful throws a fit here but this is the necessary workaround
const verifyEmail = await controller.verifyPasswordReset(
const verifyEmail = await controller.verifyEmail(
value as unknown as controller.ResetCredentials,
);

return res.render('verify email', {
return res.render('accountInit', {
id: value.id,
key: value.key,
username: verifyEmail.user,
email: verifyEmail.email,
});
}),
);
Expand Down
2 changes: 1 addition & 1 deletion views/createAccount.pug
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include include/sauce-common
| SCCS accounts are available to all Swarthmore students, faculty,
| and staff&mdash;and you'll still be able to access it after
| graduation.
form#createForm.form-signin.needs-validation(action='/account/create', method='post', novalidate)
form#createForm.form-signin.needs-validation(action='/account/init', method='post', novalidate)
.form-group.mb-3
.form-floating
script(type='text/javascript').
Expand Down
9 changes: 9 additions & 0 deletions views/verifyEmailSuccess.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
include include/sauce-common

+sauce-layout('Your request has been submitted!')(hideNavbar, includeBootstrapScripts)
h1.mb-4 We've sent you an email, follow the instructions to complete setting up your SCCS account
p.
To prevent abuse, SCCS staff manually approve all account creation
requests. When classes are in session, this usually happens within a
few hours. Once you've been approved, you'll get an email at
#{ email } with a link to set your password.

0 comments on commit 3e173aa

Please sign in to comment.