BIO.RE
Authentication

Revoke All Other Sessions

Revoke every session except the one making the request. Use this for "Sign out all other devices" UI.

POST /api/v1/auth/sessions/revoke-all โ€” ๐Ÿ”‘ User-auth (Bearer JWT) ยท Rate limit: 5 req / hour

Revokes all sessions for the authenticated user EXCEPT the current one. Pair with GET /auth/sessions to power "Sign out all other devices" buttons in account settings.

The current session (the one matching the requesting biore_refresh cookie) stays alive. Other devices' refresh tokens become invalid immediately; their access tokens expire within ~15 min.

Request

Headers

HeaderValueNotes
AuthorizationBearer <accessToken>Required
Cookie: biore_refresh=...(auto)Used to identify the current session (kept alive)

No body, no path/query params.

Response

200 OK โ€” empty body

{ "success": true }

Errors

HTTPcode / i18nKeyReason
401(no JWT or invalid)Not authenticated
429(throttle)Rate limit exceeded (5 req/hour โ€” strict; this is a destructive action)

Side effects

  1. Hash the current refresh token (SHA-256) โ†’ match against Session.refreshTokenHash to identify the current session.
  2. Update all Session rows where userId = current user AND id != current session id AND revokedAt IS NULL: set revokedAt = now().
  3. Audit log: auth.sessions.revoke_all.success (with count of sessions revoked).

Code samples

curl -X POST https://api.bio.re/api/v1/auth/sessions/revoke-all \
  -H 'Authorization: Bearer <accessToken>' \
  -b cookies.txt
async function revokeAllSessions(accessToken: string): Promise<void> {
  const res = await fetch('https://api.bio.re/api/v1/auth/sessions/revoke-all', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${accessToken}` },
    credentials: 'include',
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Revoke-all failed'), {
      code: json?.error?.code,
    });
  }
}
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { sessionKeys } from './use-sessions';

export function useRevokeAllSessions() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async () => {
      const res = await fetch('/api/v1/auth/sessions/revoke-all', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Authorization': `Bearer ${getAccessToken()}` },
      });
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Revoke-all failed'), {
          code: json?.error?.code,
        });
      }
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: sessionKeys.all });
      toast.success(t('auth.sessions.revoke_all.success'));
    },
  });
}

Try it

POST
/api/v1/auth/sessions/revoke-all
AuthorizationBearer <token>

In: header

Response Body

curl -X POST "https://loading/api/v1/auth/sessions/revoke-all"
Empty

Source

SourcePathLines
Controllerapps/api-core/src/modules/auth/auth.controller.ts282โ€“298 (revokeAllSessions)
Serviceapps/api-core/src/modules/auth/auth.service.tsrevokeAllSessions()
Prisma modelpackages/prisma/prisma/schema.prismaSession.refreshTokenHash, Session.revokedAt

On this page