diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index 916d0720..a37a5b4f 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -108,9 +108,10 @@ export class MFATicket { } /** - * Use the ticket + * @internal + * Use this ticket */ - #consume(): void { + _consume(): void { if (this.#used) throw "Already used this ticket!"; this.#used = true; } @@ -120,7 +121,7 @@ export class MFATicket { * @returns List of codes */ fetchRecoveryCodes(): Promise { - this.#consume(); + this._consume(); return this.#client.api.post("/auth/mfa/recovery", undefined, { headers: { "X-MFA-Ticket": this.token, @@ -133,7 +134,7 @@ export class MFATicket { * @returns List of codes */ async generateRecoveryCodes(): Promise { - this.#consume(); + this._consume(); const codes = await this.#client.api.patch( "/auth/mfa/recovery", @@ -154,7 +155,7 @@ export class MFATicket { * @returns Secret */ async generateAuthenticatorSecret(): Promise { - this.#consume(); + this._consume(); return ( await this.#client.api.post("/auth/mfa/totp", undefined, { headers: { @@ -168,7 +169,7 @@ export class MFATicket { * Disable authenticator */ async disableAuthenticator(): Promise { - this.#consume(); + this._consume(); await this.#client.api.delete("/auth/mfa/totp", undefined, { headers: { @@ -183,7 +184,7 @@ export class MFATicket { * Disable account */ disableAccount(): Promise { - this.#consume(); + this._consume(); return this.#client.api.post("/auth/account/disable", undefined, { headers: { "X-MFA-Ticket": this.token, @@ -195,7 +196,7 @@ export class MFATicket { * Delete account */ deleteAccount(): Promise { - this.#consume(); + this._consume(); return this.#client.api.post("/auth/account/delete", undefined, { headers: { "X-MFA-Ticket": this.token, diff --git a/src/classes/Session.ts b/src/classes/Session.ts index bbf244ec..80bdcb30 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -2,6 +2,8 @@ import { decodeTime } from "ulid"; import type { SessionCollection } from "../collections/SessionCollection.js"; +import { MFATicket } from "./MFA.js"; + /** * Session Class */ @@ -70,8 +72,17 @@ export class Session { /** * Delete a session */ - async delete(): Promise { - await this.#collection.client.api.delete(`/auth/session/${this.id as ""}`); + async delete(ticket: MFATicket): Promise { + ticket._consume(); + await this.#collection.client.api.delete( + `/auth/session/${this.id as ""}`, + undefined, + { + headers: { + "X-MFA-Ticket": ticket.token, + }, + }, + ); this.#collection.delete(this.id); } } diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index acae155c..c60590f8 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -2,6 +2,7 @@ import { batch } from "solid-js"; import type { SessionInfo } from "stoat-api"; +import { MFATicket } from "../classes/MFA.js"; import { Session } from "../classes/Session.js"; import type { HydratedSession } from "../hydration/session.js"; @@ -29,10 +30,19 @@ export class SessionCollection extends ClassCollection< * Delete all sessions, optionally including self * @param revokeSelf Whether to remove current session too */ - async deleteAll(revokeSelf = false): Promise { - await this.client.api.delete("/auth/session/all", { - revoke_self: revokeSelf, - }); + async deleteAll(ticket: MFATicket, revokeSelf = false): Promise { + ticket._consume(); + await this.client.api.delete( + "/auth/session/all", + { + revoke_self: revokeSelf, + }, + { + headers: { + "X-MFA-Ticket": ticket.token, + }, + }, + ); for (const entry of this.toList()) { if (!revokeSelf && entry.current) continue;