mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-08-31 08:11:27 +02:00
77 lines
2.5 KiB
Go
77 lines
2.5 KiB
Go
package devicelogin
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/italypaleale/francis/host/local"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
|
|
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
|
"github.com/pocket-id/pocket-id/backend/internal/model"
|
|
)
|
|
|
|
type TokenService interface {
|
|
GenerateAccessToken(user model.User, authenticationMethod string, sessionDuration time.Duration) (string, error)
|
|
}
|
|
|
|
type ReauthenticationTokenConsumer interface {
|
|
ConsumeReauthenticationToken(ctx context.Context, tx *gorm.DB, token string, userID string) (time.Time, error)
|
|
}
|
|
|
|
type AuditLogger interface {
|
|
Create(ctx context.Context, event model.AuditLogEvent, ipAddress, userAgent, userID string, data model.AuditLogData, tx *gorm.DB) (model.AuditLog, bool)
|
|
DeviceStringFromUserAgent(userAgent string) string
|
|
}
|
|
|
|
type IPLocationResolver interface {
|
|
GetLocationByIP(ctx context.Context, ipAddress string) (country string, city string, err error)
|
|
}
|
|
|
|
type Dependencies struct {
|
|
DB *gorm.DB
|
|
Actors *local.Host
|
|
BaseURL string
|
|
|
|
Signer TokenService
|
|
Reauth ReauthenticationTokenConsumer
|
|
AuditLog AuditLogger
|
|
IPLocator IPLocationResolver
|
|
AppConfig appconfig.AppConfigResolver
|
|
}
|
|
|
|
type Module struct {
|
|
service *Service
|
|
handler *handler
|
|
}
|
|
|
|
func New(deps Dependencies) (*Module, error) {
|
|
service := NewService(deps.Actors.Service(), deps.DB, deps.Signer, deps.Reauth, deps.AuditLog, deps.IPLocator)
|
|
module := &Module{
|
|
service: service,
|
|
handler: newHandler(service, deps.BaseURL, deps.AppConfig),
|
|
}
|
|
|
|
// Register the durable request actor before the host starts
|
|
err := deps.Actors.RegisterActor(
|
|
requestActorType,
|
|
newRequestActor,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to register device login actor: %w", err)
|
|
}
|
|
|
|
return module, nil
|
|
}
|
|
|
|
// RegisterRoutes mounts the public exchange and authenticated verification endpoints
|
|
func (m *Module) RegisterRoutes(apiGroup *gin.RouterGroup, browserAuth, createRateLimit, exchangeRateLimit, verificationRateLimit gin.HandlerFunc) {
|
|
apiGroup.POST("/device-login/requests", createRateLimit, httpserver.Handle(m.handler.createRequest))
|
|
apiGroup.POST("/device-login/requests/:id/exchange", exchangeRateLimit, httpserver.Handle(m.handler.exchangeRequest))
|
|
apiGroup.POST("/device-login/verification", verificationRateLimit, browserAuth, httpserver.Handle(m.handler.inspectRequest))
|
|
apiGroup.POST("/device-login/verification/decision", verificationRateLimit, browserAuth, httpserver.Handle(m.handler.decideRequest))
|
|
}
|