Skip to content

Commit

Permalink
fix(email): fix email verification
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienZ committed Oct 3, 2024
1 parent 3e49ffb commit c325aea
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 3 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ Registers a new user in the database if they don’t already exist, email + pass

##### `login(values: ILoginUserParams): Promise<[ string, SlipAuthPublicSession]>`

Email + password login. Creates a session in database
##### `askEmailVerificationCode(user: SlipAuthUser): Promise<void>`

Ask the email verification code for a user.
##### `verifyEmailVerificationCode(user: SlipAuthUser, code: string): Promise<boolean>`

Checks the email verification code. Returns a boolean.
Expand All @@ -163,6 +164,10 @@ Don't forget to re-login after verifying the email verification code.
Registers a new user in the database if they don’t already exist. It handles OAuth authentication by registering the OAuth account, creating a session, and linking the user’s details.
- **Returns**: A tuple containing the user ID and the created session details.

##### `getUser(userId: string)`

Fetches a user by its user ID.

##### `getSession(sessionId: string)`

Fetches a session by its session ID.
Expand Down
2 changes: 2 additions & 0 deletions playground/server/routes/auth/login.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ export default defineEventHandler(async (event) => {
...body,
ua: getHeader(event, "User-Agent"),
});
const user = await auth.getUser(userId);

await setUserSession(event, {
expires_at: session.expires_at,
id: session.id,
user: {
id: userId,
email_verified: user?.email_verified ?? false,
},
});
return sendRedirect(event, "/");
Expand Down
5 changes: 4 additions & 1 deletion playground/server/routes/auth/register.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ export default defineEventHandler(async (event) => {
ua: getHeader(event, "User-Agent"),
});

const user = await auth.getUser(userId);

await setUserSession(event, {
expires_at: session.expires_at,
id: session.id,
user: {
id: userId,
email_verified: user?.email_verified ?? false,
},
});
return sendRedirect(event, "/");
return sendRedirect(event, "/profile");
});
13 changes: 12 additions & 1 deletion src/runtime/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class SlipAuthCore {

try {
const user = await this.#repos.users.insert(userId, email, passwordHash);
await this.#repos.emailVerificationCodes.insert(user.id, user.email, this.#createRandomEmailVerificationCode());
this.askEmailVerificationCode(user);
const sessionToLoginId = this.#createRandomSessionId();
const sessionToLogin = await this.#repos.sessions.insert(sessionToLoginId, {
userId: user.id,
Expand Down Expand Up @@ -231,6 +231,11 @@ export class SlipAuthCore {
throw new Error("could not find oauth user");
}

public async askEmailVerificationCode(user: SlipAuthUser): Promise<void> {
await this.#repos.emailVerificationCodes.deleteAllByUserId(user.id);
await this.#repos.emailVerificationCodes.insert(user.id, user.email, this.#createRandomEmailVerificationCode());
}

// TODO: use transactions
// should recreate session if true
public async verifyEmailVerificationCode(user: SlipAuthUser, code: string): Promise<boolean> {
Expand All @@ -252,6 +257,8 @@ export class SlipAuthCore {
return false;
}

await this.#repos.users.updateEmailVerifiedByUserId(databaseCode.user_id, true);

return true;
}

Expand Down Expand Up @@ -348,6 +355,10 @@ export class SlipAuthCore {
this.#passwordHashingMethods = methods;
}

public getUser(userId: string) {
return this.#repos.users.findById(userId);
}

public getSession(sessionId: string) {
return this.#repos.sessions.findById(sessionId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ export class EmailVerificationCodesRepository extends TableRepository<"emailVeri
return code;
}

async deleteAllByUserId(userId: string): Promise<void> {
await this._orm
.delete(this.table)
.where(
eq(this.table.user_id, userId),
)
.run();
}

async deleteById(codeId: number) {
const codeToDelete = await this.findById(codeId);

Expand Down
10 changes: 10 additions & 0 deletions src/runtime/core/repositories/UsersRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,14 @@ export class UsersRepository extends TableRepository<"users"> {
.where(eq(this.table.id, userId))
.run();
};

updateEmailVerifiedByUserId = async (userId: string, value: boolean): Promise<void> => {
return await this._orm
.update(this.table)
.set({
email_verified: value,
})
.where(eq(this.table.id, userId))
.run();
};
}
3 changes: 3 additions & 0 deletions tests/core-email-password.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ describe("SlipAuthCore", () => {
const verification = await auth.verifyEmailVerificationCode(fakeUserData as SlipAuthUser, codes[0].code);

expect(verification).toBe(true);

const dbUser = await auth.getUser(userId);
expect(dbUser?.email_verified).toBe(1);
});
});
});

0 comments on commit c325aea

Please sign in to comment.