Core integration
The wheel installsplugins.email_otp. Its metadata mounts the URL namespace at /otp/, marks the sign-in route public, and contributes Email me a sign-in code to Core’s generic sign-in options.
Model and lifecycle
EmailOTP stores the normalized email, business ID, hashed code, creation/expiration times, used state, and verification-attempt count.
/otp/signin/validates an email and enforces the cooldown.- Existing active codes for that email/business are invalidated.
- A hashed six-digit code is saved and the plaintext code is sent by email.
/otp/signin/verify/validates expiry, use state, attempt count, and the hash.- A matching active profile is authenticated; otherwise the verified email is carried into signup.
Routes
/otp/signin/: request a code (email_otp:request)./otp/signin/verify/: submit and verify a code (email_otp:verify).
