or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-interface.mdcore-authentication.mddevice-models.mddjango-integration.mdemail-devices.mdhotp-devices.mdindex.mdoath-algorithms.mdstatic-tokens.mdtotp-devices.md

email-devices.mddocs/

0

# Email Devices

1

2

One-time passwords delivered via email, useful for users who don't have smartphone access to authenticator apps or as a backup authentication method.

3

4

## Capabilities

5

6

### EmailDevice Model

7

8

```python { .api }

9

class EmailDevice(TimestampMixin, CooldownMixin, ThrottlingMixin, SideChannelDevice):

10

"""

11

Email-based OTP device with cooldown and throttling.

12

13

Fields:

14

- email: EmailField(blank=True) - Alternative email address

15

"""

16

17

email = models.EmailField(blank=True)

18

19

def generate_challenge(self, extra_context=None):

20

"""

21

Generate and email OTP token to user.

22

23

Parameters:

24

- extra_context: dict - Additional template context

25

26

Returns:

27

bool - True if challenge was generated and sent

28

"""

29

30

def get_subject(self) -> str:

31

"""Get email subject line."""

32

33

def send_mail(self, body, **kwargs):

34

"""

35

Send email with OTP token.

36

37

Parameters:

38

- body: str - Email body content

39

- **kwargs: Additional email parameters

40

"""

41

42

def get_cooldown_duration(self) -> int:

43

"""Return cooldown duration from settings."""

44

45

def get_throttle_factor(self) -> int:

46

"""Return throttle factor from settings."""

47

```

48

49

### Admin Interface

50

51

```python { .api }

52

class EmailDeviceAdmin(admin.ModelAdmin):

53

"""Admin interface for EmailDevice."""

54

```

55

56

### Configuration

57

58

```python { .api }

59

class OTPEmailSettings(Settings):

60

"""Email plugin settings with defaults."""

61

```

62

63

## Usage Examples

64

65

### Creating Email Devices

66

67

```python

68

from django_otp.plugins.otp_email.models import EmailDevice

69

70

# Create email device using user's email

71

device = EmailDevice.objects.create(

72

user=user,

73

name='Email OTP',

74

confirmed=True

75

)

76

77

# Create with alternative email

78

device = EmailDevice.objects.create(

79

user=user,

80

name='Backup Email',

81

email='backup@example.com', # Different from user.email

82

confirmed=True

83

)

84

```

85

86

### Generating and Verifying Email Tokens

87

88

```python

89

def send_email_otp(user):

90

"""Send OTP token via email."""

91

92

try:

93

device = EmailDevice.objects.get(user=user, confirmed=True)

94

95

# Check if generation is allowed (cooldown)

96

if device.generate_is_allowed() != True:

97

return False, "Please wait before requesting another code"

98

99

# Generate and send token

100

success = device.generate_challenge()

101

return success, "Code sent to email" if success else "Failed to send code"

102

103

except EmailDevice.DoesNotExist:

104

return False, "No email device configured"

105

106

def verify_email_otp(user, token):

107

"""Verify email OTP token."""

108

109

try:

110

device = EmailDevice.objects.get(user=user, confirmed=True)

111

112

if device.verify_token(token):

113

return True, "Token verified successfully"

114

else:

115

return False, "Invalid or expired token"

116

117

except EmailDevice.DoesNotExist:

118

return False, "No email device configured"

119

```

120

121

## Configuration Settings

122

123

```python

124

# settings.py

125

126

# Email settings

127

OTP_EMAIL_SENDER = 'noreply@example.com'

128

OTP_EMAIL_SUBJECT = 'Your verification code'

129

130

# Token validity (default: 300 seconds)

131

OTP_EMAIL_TOKEN_VALIDITY = 600

132

133

# Cooldown duration (default: 30 seconds)

134

OTP_EMAIL_COOLDOWN_DURATION = 60

135

136

# Throttling factor (default: 1)

137

OTP_EMAIL_THROTTLE_FACTOR = 2

138

139

# Email templates

140

OTP_EMAIL_BODY_TEMPLATE = 'Your verification code is: {token}'

141

OTP_EMAIL_BODY_TEMPLATE_PATH = 'otp/email_body.txt'

142

OTP_EMAIL_BODY_HTML_TEMPLATE_PATH = 'otp/email_body.html'

143

```

144

145

## Email Templates

146

147

### Text Template (email_body.txt)

148

149

```

150

Your verification code is: {{ token }}

151

152

This code will expire in {{ valid_minutes }} minutes.

153

154

If you did not request this code, please ignore this email.

155

```

156

157

### HTML Template (email_body.html)

158

159

```html

160

<h2>Verification Code</h2>

161

<p>Your verification code is: <strong>{{ token }}</strong></p>

162

<p>This code will expire in {{ valid_minutes }} minutes.</p>

163

<p><small>If you did not request this code, please ignore this email.</small></p>

164

```