mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-02-16 01:19:46 +02:00
128 lines
3.4 KiB
Go
128 lines
3.4 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/pocketbase/pocketbase/tools/types"
|
|
)
|
|
|
|
const CollectionNameOTPs = "_otps"
|
|
|
|
var (
|
|
_ Model = (*OTP)(nil)
|
|
_ PreValidator = (*OTP)(nil)
|
|
_ RecordProxy = (*OTP)(nil)
|
|
)
|
|
|
|
// OTP defines a Record proxy for working with the otps collection.
|
|
type OTP struct {
|
|
*Record
|
|
}
|
|
|
|
// NewOTP instantiates and returns a new blank *OTP model.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// otp := core.NewOTP(app)
|
|
// otp.SetRecordRef(user.Id)
|
|
// otp.SetCollectionRef(user.Collection().Id)
|
|
// otp.SetPassword(security.RandomStringWithAlphabet(6, "1234567890"))
|
|
// app.Save(otp)
|
|
func NewOTP(app App) *OTP {
|
|
m := &OTP{}
|
|
|
|
c, err := app.FindCachedCollectionByNameOrId(CollectionNameOTPs)
|
|
if err != nil {
|
|
// this is just to make tests easier since otp is a system collection and it is expected to be always accessible
|
|
// (note: the loaded record is further checked on OTP.PreValidate())
|
|
c = NewBaseCollection("__invalid__")
|
|
}
|
|
|
|
m.Record = NewRecord(c)
|
|
|
|
return m
|
|
}
|
|
|
|
// PreValidate implements the [PreValidator] interface and checks
|
|
// whether the proxy is properly loaded.
|
|
func (m *OTP) PreValidate(ctx context.Context, app App) error {
|
|
if m.Record == nil || m.Record.Collection().Name != CollectionNameOTPs {
|
|
return errors.New("missing or invalid otp ProxyRecord")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProxyRecord returns the proxied Record model.
|
|
func (m *OTP) ProxyRecord() *Record {
|
|
return m.Record
|
|
}
|
|
|
|
// SetProxyRecord loads the specified record model into the current proxy.
|
|
func (m *OTP) SetProxyRecord(record *Record) {
|
|
m.Record = record
|
|
}
|
|
|
|
// CollectionRef returns the "collectionRef" field value.
|
|
func (m *OTP) CollectionRef() string {
|
|
return m.GetString("collectionRef")
|
|
}
|
|
|
|
// SetCollectionRef updates the "collectionRef" record field value.
|
|
func (m *OTP) SetCollectionRef(collectionId string) {
|
|
m.Set("collectionRef", collectionId)
|
|
}
|
|
|
|
// RecordRef returns the "recordRef" record field value.
|
|
func (m *OTP) RecordRef() string {
|
|
return m.GetString("recordRef")
|
|
}
|
|
|
|
// SetRecordRef updates the "recordRef" record field value.
|
|
func (m *OTP) SetRecordRef(recordId string) {
|
|
m.Set("recordRef", recordId)
|
|
}
|
|
|
|
// SentTo returns the "sentTo" record field value.
|
|
//
|
|
// It could be any string value (email, phone, message app id, etc.)
|
|
// and usually is used as part of the auth flow to update the verified
|
|
// user state in case for example the sentTo value matches with the user record email.
|
|
func (m *OTP) SentTo() string {
|
|
return m.GetString("sentTo")
|
|
}
|
|
|
|
// SetSentTo updates the "sentTo" record field value.
|
|
func (m *OTP) SetSentTo(val string) {
|
|
m.Set("sentTo", val)
|
|
}
|
|
|
|
// Created returns the "created" record field value.
|
|
func (m *OTP) Created() types.DateTime {
|
|
return m.GetDateTime("created")
|
|
}
|
|
|
|
// Updated returns the "updated" record field value.
|
|
func (m *OTP) Updated() types.DateTime {
|
|
return m.GetDateTime("updated")
|
|
}
|
|
|
|
// HasExpired checks if the otp is expired, aka. whether it has been
|
|
// more than maxElapsed time since its creation.
|
|
func (m *OTP) HasExpired(maxElapsed time.Duration) bool {
|
|
return time.Since(m.Created().Time()) > maxElapsed
|
|
}
|
|
|
|
func (app *BaseApp) registerOTPHooks() {
|
|
recordRefHooks[*OTP](app, CollectionNameOTPs, CollectionTypeAuth)
|
|
|
|
// run on every hour to cleanup expired otp sessions
|
|
app.Cron().Add("__otpsCleanup__", "0 * * * *", func() {
|
|
if err := app.DeleteExpiredOTPs(); err != nil {
|
|
app.Logger().Warn("Failed to delete expired OTP sessions", "error", err)
|
|
}
|
|
})
|
|
}
|