---
url: "https://vueda.dev/v3/reference/api/py/vueda.user.viewsets/TOTPDeviceViewSet.md"
title: "TOTPDeviceViewSet"
---

# TOTPDeviceViewSet

## Overview

List, set up, activate, and remove the signed-in user's two-factor devices.

All of a user's devices share one allauth TOTP ``Authenticator`` and its secret. Sign-in codes for email and
SMS are computed from the stored secret when they are sent, so the authenticator app is the only device that
holds a copy of the secret. Adding or removing the app therefore gives the authenticator a new secret, which
leaves the email and SMS devices working and stops any earlier copy of the app from producing valid codes.

## `activate` {#activate}

Confirm the ``code`` for the device that ``setup`` started, and add the device.

The code is checked against the setup secret. The first device creates the user's TOTP authenticator with
that secret. An authenticator app added to an existing authenticator replaces its secret with the setup
secret. An email or SMS device joins the existing authenticator and leaves its secret unchanged.

### Signature {#activate-signature}

`activate(self, request)`

#### Parameters {#activate-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="activate-param-request">request</span> |  | yes |  |  |

### Source {#activate-source}

`server/vueda/core/decorators.py:150`

## `destroy` {#destroy}

Remove one device by ``pk``, or several by ``pks`` in the request body.

Removing the last device turns two-factor authentication off. Removing the authenticator app while other
devices remain gives the authenticator a new secret, so the removed app's codes stop working.

### Signature {#destroy-signature}

`destroy(self, request, args, kwargs)`

#### Parameters {#destroy-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="destroy-param-request">request</span> |  | yes |  |  |
| <span id="destroy-param-args">args</span> |  | no |  |  |
| <span id="destroy-param-kwargs">kwargs</span> |  | no |  |  |

### Source {#destroy-source}

`server/vueda/core/decorators.py:217`

## `get_queryset` {#get_queryset}

Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using `self.queryset`.

This method should always be used rather than accessing `self.queryset`
directly, as `self.queryset` gets evaluated only once, and those results
are cached for all subsequent requests.

You may want to override this if you need to provide different
querysets depending on the incoming request.

(Eg. return a list of items that is specific to the user)

### Signature {#get_queryset-signature}

`get_queryset(self)`

#### Parameters {#get_queryset-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |

### Source {#get_queryset-source}

`server/vueda/user/viewsets.py:58`

## `setup` {#setup}

Start setting up a two-factor device with the requested ``method``.

Each setup generates a new setup secret and keeps it in the session. For ``totp`` (an authenticator app),
returns that secret and its QR code. For ``email`` and ``sms``, sends a code from that secret to
``destination``, so the code proves that the user receives messages there and does not confirm sign-in.
The device is added when ``activate`` confirms the code.

### Signature {#setup-signature}

`setup(self, request)`

#### Parameters {#setup-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="setup-param-request">request</span> |  | yes |  |  |

### Source {#setup-source}

`server/vueda/core/decorators.py:75`

## `TOTP_SESSION_KEY` {#TOTP_SESSION_KEY}

## `basename` {#basename}

## `description` {#description}

## `detail` {#detail}

## `detail_args` {#detail_args}

## `filterset_class` {#filterset_class}

## `name` {#name}

## `permission_classes` {#permission_classes}

## `queryset` {#queryset}

## `serializer_class` {#serializer_class}

## `suffix` {#suffix}

## Source

`server/vueda/user/viewsets.py:41`
