Repository navigation
Session revocation support for password reset #775
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
base: reboot
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -536,15 +536,19 @@ export function setupEmailPassword<UsersTable extends string>( | |
| /** | ||
| * Change the signed-in user's password. Requires the session *and* the | ||
| * current password (OWASP ASVS v5 6.2.3), and notifies the primary | ||
| * email address (ASVS 6.3.7). | ||
| * email address (ASVS 6.3.7). Signs out the user's other sessions | ||
| * unless `signOutOtherSessions` is `false` (ASVS v5 7.4.3). | ||
| */ | ||
| // TODO: option to invalidate the user's other sessions. | ||
| changePassword: authMutation({ | ||
| args: { currentPassword: v.string(), newPassword: v.string() }, | ||
| args: { | ||
| currentPassword: v.string(), | ||
| newPassword: v.string(), | ||
| signOutOtherSessions: v.optional(v.boolean()), | ||
| }, | ||
| returns: changePasswordResult, | ||
| handler: async ( | ||
| ctx, | ||
| { currentPassword, newPassword }, | ||
| { currentPassword, newPassword, signOutOtherSessions = true }, | ||
| ): Promise<ChangePasswordResult> => { | ||
| const userId = await getAuthUserId(ctx, core.component); | ||
| if (userId === null) { | ||
|
|
@@ -592,6 +596,12 @@ export function setupEmailPassword<UsersTable extends string>( | |
| return { success: false, userError: setResult.userError }; | ||
| } | ||
|
|
||
| // The current password was just verified, so the caller owns this | ||
| // session: sign out the user's other sessions if requested. | ||
| if (signOutOtherSessions) { | ||
|
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. P1: This revokes sessions only for Prompt for AI agents
Collaborator
Author
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. That's in another PR. |
||
| await ctx.convexAuth.revokeOtherSessions(); | ||
| } | ||
|
|
||
| const to = await ctx.runQuery( | ||
| component.verifiedEmails.getPrimaryEmail, | ||
| { userId }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,3 @@ | ||
| import { mutationGeneric } from "convex/server"; | ||
| import { Infer, v } from "convex/values"; | ||
| import { getAuthUserId } from "../../server/userId.ts"; | ||
| import { | ||
|
|
@@ -272,14 +271,19 @@ export function setupUsernamePassword<UsersTable extends string>( | |
|
|
||
| /** | ||
| * Change the password of the signed-in user. The user must re-authenticate | ||
| * by giving their current password. | ||
| * by giving their current password. Signs out the user's other sessions | ||
| * unless `signOutOtherSessions` is `false`. | ||
| */ | ||
| changePassword: mutationGeneric({ | ||
| args: { currentPassword: v.string(), newPassword: v.string() }, | ||
| changePassword: authMutation({ | ||
| args: { | ||
| currentPassword: v.string(), | ||
| newPassword: v.string(), | ||
| signOutOtherSessions: v.optional(v.boolean()), | ||
|
Member
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. What do you think about making this default to Pilcrow says the following about this:
|
||
| }, | ||
| returns: changePasswordResult, | ||
| handler: async ( | ||
| ctx, | ||
| { currentPassword, newPassword }, | ||
| { currentPassword, newPassword, signOutOtherSessions = true }, | ||
| ): Promise<ChangePasswordResult> => { | ||
| const userId = await getAuthUserId(ctx, core.component); | ||
| if (userId === null) { | ||
|
|
@@ -333,7 +337,11 @@ export function setupUsernamePassword<UsersTable extends string>( | |
| ); | ||
| } | ||
|
|
||
| // TODO(nicolas) Allow the user to choose to revoke their existing sessions here (needs core support) | ||
| // The current password was just verified, so the caller owns this | ||
| // session: sign out the user's other sessions if requested. | ||
| if (signOutOtherSessions) { | ||
| await ctx.convexAuth.revokeOtherSessions(); | ||
| } | ||
| return { success: true }; | ||
| }, | ||
| }), | ||
|
|
||
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.
What is this style doing? Fixing the margins?